package yf.mall.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.github.pagehelper.PageHelper;
import com.yf.request.SearchParam;
import com.yf.response.R;
import com.yf.service.SmsService;
import com.yf.service.WxPayService;
import com.yf.utils.DateUtil;
import com.yf.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.springframework.context.annotation.Lazy;
import yf.mall.common.Const;
import com.yf.response.RRException;
import com.yf.service.impl.BaseServiceImpl;
import yf.mall.dao.*;
import yf.mall.entity.*;
import yf.mall.enums.*;
import yf.mall.service.*;
import yf.mall.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import org.springframework.transaction.annotation.Transactional;
import yf.mall.vo.down.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 商品订单Service实现类
 *
 * @author hxf
 * @email 505860922@qq.com
 * @date Tue Aug 13 14:26:20 CST 2019
 */
@Service
@Slf4j
public class MallOrderServiceImpl extends BaseServiceImpl<MallOrderEntity> implements MallOrderService {

    private MallOrderDao mallOrderDao;

    @Autowired
    private CartService cartService;

    @Autowired
    private MallGoodsDao mallGoodsDao;

    @Autowired
    private OrderItemDao orderItemDao;

    @Autowired
    private UserService userService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private PriceService priceService;

    @Autowired
    private LevelDao levelDao;

    @Autowired
    private MallCardDao mallCardDao;

    @Autowired
    private MallActService mallActService;

    @Lazy
    @Resource
    private MallStoreService mallStoreService;

    @Autowired
    private MallActService actService;


    @Autowired
    public void setDao(MallOrderDao mallOrderDao) {
        this.mallOrderDao = mallOrderDao;
        super.setBaseDao(mallOrderDao);
    }


    /**
     * 内部方法
     **/

    //创建订单号
    private String createNO(Long userId) {
        return System.currentTimeMillis() + "" + Math.round(Math.random() * 100) + "" + userId;
    }

    //退回物流费
    private void backLogFee(MallOrderEntity entity) {
        //物流费多收
        MallOrderEntity tem = mallOrderDao.get(entity.getId());
        BigDecimal td = tem.getLogFee().subtract(entity.getLogFee());
        if (td.compareTo(BigDecimal.ZERO) > 0) {
            accountService.transfer(Const.ADMIN_ID, getRetailUserId(entity), AccountTypeEnum.CASH.getIndex(), td, "物流费退回:" + tem.getOrderNo());
        }
    }

    //退回物流费
    private void backLogFee(Long orderId, BigDecimal logFee) {
        //物流费多收
        MallOrderEntity tem = mallOrderDao.get(orderId);
        log.info("orderId:" + orderId);
        log.info(tem.getLogFee() + "物流费退回中" + logFee);
        BigDecimal td = tem.getLogFee().subtract(logFee);
        if (td.compareTo(BigDecimal.ZERO) > 0) {
            accountService.transfer(Const.ADMIN_ID, getRetailUserId(tem), AccountTypeEnum.CASH.getIndex(), td, "物流费退回:" + tem.getOrderNo());
        }
    }

    //获取实际当事人
    Long getRetailUserId(MallOrderEntity orderEntity) {
        Long userId = orderEntity.getFromUserId();
        if (userId.equals(Const.ADMIN_ID)) {
            userId = orderEntity.getUserId();
        }
        return userId;
    }



    /**
     * 外部方法实现 TODO  扣减库存
     **/

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public String commitOrder(Long userId, AddressEntity address, String remark, Integer payWay, Integer orderType, String noticeUrl) {
//        List<CartEntity> cartEntities = cartService.findByUserIdWithSelected(userId);
//        if (cartEntities.isEmpty()) {
//            throw new RRException("购物车为空!");
//        }
//        //验证是否可以下单
//        validateCommitOrder(cartEntities, orderType, userId, remark);
//        //创建订单
//        MallOrderEntity orderEntity = buildBuyOrder(Const.ADMIN_ID,userId, orderType, address, remark, payWay);
//        //生成订单明细 且统计明细的价格 券 物流费
//        buildOrderItem(orderEntity, cartEntities);
//        //支付之前
//        beforePay(orderEntity);
//        mallOrderDao.update(orderEntity);
//        //代金券的方式直接支付
//        if (payWay.equals(MallOrderPayWayEnum.CASH.getIndex())) {
//            payByAccount(orderEntity);
//            return null;
//        } else {//统一下单 TODO 前端如果返回ZERO 代表不需要付钱直接支付成功
//            return unionOrder(orderEntity, noticeUrl);
//        }
//
//    }

    //
    public Boolean validateVip(Long vipUserId, List<CartEntity> cartEntities, Long userId) {
        if (vipUserId != null) {
            return false;
        }
        //自己的级别
        UserEntity user = userDao.get(userId);
        //开启负责人奖励 触发级别 触发利润大于0
        for (CartEntity cartEntity : cartEntities) {
            if (isVip(cartEntity.getGoodsId(), userId, user.getTCode())) {
                return true;
            }
        }
        return false;
    }

//    public Boolean isVip(Long goodsId,String levelName){
//        MallGoodsEntity goodsEntity = mallGoodsDao.get(goodsId);
//        if (goodsEntity.getVip() == 1 && goodsEntity.getVipLevel() != null && goodsEntity.getVipLevel().contains(levelName) && goodsEntity.getVipProfit() != null && goodsEntity.getVipProfit() != null) {
//            return true;
//        }
//        return false;
//    }

    //触发级别
    public Boolean isVip(Long goodsId, Long userId, String code) {
        MallGoodsEntity goodsEntity = mallGoodsDao.get(goodsId);
        if (!goodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())&&!goodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex())) {
            return false;
        }
        PriceEntity priceEntity = priceService.findByUserIdAndGoodsIdAndCode(userId, goodsId, code);
        if (priceEntity.getVip() == 1) {
            return true;
        }
        return false;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String commitOrder(Long userId, Long vipUserId, AddressEntity address, String remark, Integer payWay, Integer orderType, String noticeUrl, Integer temp, Long recordId,Long[] cardIds,Long teamId,Long shareId) {
        List<CartEntity> cartEntities = cartService.findByUserIdWithSelected(userId);
        if (cartEntities.isEmpty()) {
            throw new RRException("购物车 为空!");
        }
        //需要VIP
        if (validateVip(vipUserId, cartEntities, userId)) {
            return "VIP";
        }
        //验证是否可以下单
        validateCommitOrder(cartEntities, orderType, userId, remark, address, temp, recordId, payWay,shareId);
        //创建订单
        List<MallOrderEntity> orderEntities = buildBuyOrder(cartEntities, userId, orderType, address, remark, payWay, temp);
        for (MallOrderEntity orderEntity : orderEntities) {
            orderEntity.setVipUserId(vipUserId);
            if(teamId!=null){
                UserEntity user = userDao.get(teamId);
                orderEntity.setTeamCode(user.getCode());
                orderEntity.setTeamId(teamId);
             }
            if(shareId!=null){
                UserEntity user = userDao.get(shareId);
                orderEntity.setShareId(shareId);
                orderEntity.setShareCode(user.getCode());
            }
        }
        //支付之前
        String info = beforePay(userId, orderEntities, recordId,cardIds);
        //代金券的方式直接支付
        if (payWay.equals(MallOrderPayWayEnum.CASH.getIndex())) {
            payByAccount(orderEntities);
            return info;
        } else {//统一下单 TODO 前端如果返回ZERO 代表不需要付钱直接支付成功
            MallOrderEntity orderEntity;
            if (orderEntities.size() > 1) { //多个店铺订单
                orderEntity = combineOrder(userId, orderEntities);
            } else {
                orderEntity = orderEntities.get(0);
            }

            return unionOrder(orderEntity, noticeUrl);
        }

    }


    //即将支付之前 扣掉优惠券 移除提货卡
    String beforePay(Long userId, List<MallOrderEntity> orderEntitys, Long recordId,Long[] cardIds) {
        //清除购物车
        cartService.deleteSelected(userId);
        String info = "";
        for (MallOrderEntity orderEntity : orderEntitys) {
            BigDecimal cardPrice = actService.getCardPrice(orderEntity);
            //使用掉提货卡
            actService.useCard(orderEntity);

            //使用掉券
            info = actService.useTicket(orderEntity, cardPrice, recordId,cardIds);
            update(orderEntity);
        }
        return info;
    }


    /**
     * 创建商城下单订单
     *
     * @param userId
     * @param cartEntities
     */
    private MallOrderEntity buildBuyOrder(Long fromUserId, Long userId, Integer orderType, AddressEntity address, String remark, Integer payWay, Integer temp) {
        MallOrderEntity orderEntity;
        Integer busType = MallOrderBusTypeEnum.BUY.getIndex();
        BigDecimal price = BigDecimal.ZERO;
        BigDecimal logFee = BigDecimal.ZERO;
        Date payTime = null;
        Integer payStatus = MallOrderPayStatusEnum.NOT_PAID.getIndex();
        Integer mention = MallActRewardTypeEnum.no.getIndex();
        if (temp != null && temp == 1) {
            mention = MallActRewardTypeEnum.yes.getIndex();
        }
        Integer quantity = 0;
        Integer orderStatus = MallOrderOrderStatusEnum.NEW.getIndex();
        BigDecimal point = BigDecimal.ZERO;
        BigDecimal coupon = BigDecimal.ZERO;
        BigDecimal voucher = BigDecimal.ZERO;
        BigDecimal clear = BigDecimal.ZERO;
        if (orderType.equals(MallOrderOrderTypeEnum.TRANSFER.getIndex())) {
            //商城转货订单
            orderEntity = new MallOrderEntity(createNO(userId), fromUserId, orderType, busType, payWay, userId, price, quantity, new Date(), new Date(), orderStatus, payStatus, point, coupon, voucher, remark, clear, mention, fromUserId);
        } else {
            //商城发货订单
            orderEntity = new MallOrderEntity(createNO(userId), fromUserId, orderType, busType, payWay, userId, price, quantity, new Date(), payTime, orderStatus, payStatus, logFee, address.getUserName(), address.getMobile(), address.getProvince(), address.getCity(), address.getCounty(), address.getDetail(), point, coupon, voucher, remark, mention, clear, fromUserId);
            orderEntity.setOrderStatus(MallOrderPayStatusEnum.NOT_PAID.getIndex());
        }
        //生成订单
        mallOrderDao.save(orderEntity);
        return orderEntity;
    }


    /**
     * 创建订单且拆分订单
     *
     * @param userId
     * @param address
     * @param remark
     * @param payWay
     * @param orderType
     * @return
     */
    private List<MallOrderEntity> buildBuyOrder(List<CartEntity> cartEntities, Long userId, Integer orderType, AddressEntity address, String remark, Integer payWay, Integer temp) {
        List<MallOrderEntity> mallOrderEntities = new ArrayList<>();
        HashMap<Long, List<CartEntity>> map = new HashMap<>();
        //把订单按照公司区分
        for (CartEntity cartEntity : cartEntities) {
            Long shopUserId = mallGoodsDao.get(cartEntity.getGoodsId()).getUserId();
            if (shopUserId == null) { //默认是公司的
                shopUserId = Const.ADMIN_ID;
            }
            if (map.containsKey(shopUserId)) {
                map.get(shopUserId).add(cartEntity);
            } else {
                List<CartEntity> list = new ArrayList<>();
                list.add(cartEntity);
                map.put(shopUserId, list);
            }
        }
        //分开组件订单
        for (Long shopId : map.keySet()) {
            MallOrderEntity mallOrderEntity = buildBuyOrder(shopId, userId, orderType, address, remark, payWay, temp);
            buildOrderItem(mallOrderEntity, map.get(shopId));
            mallOrderEntities.add(mallOrderEntity);
        }
        return mallOrderEntities;
    }

    /**
     * 组合订单 计算组合订单价格
     *
     * @return
     */
    private MallOrderEntity combineOrder(Long userId, List<MallOrderEntity> orderEntities) {
        BigDecimal payPrice = BigDecimal.ZERO;
        List<String> orderNos = new ArrayList<>();
        for (MallOrderEntity orderEntity : orderEntities) {
            orderNos.add(orderEntity.getOrderNo());
            payPrice = payPrice.add(getRetailPrice(orderEntity));
        }
        //生成虚拟单号
        String unionNo = createNO(userId);
        //绑定订单编号
        orderUnionService.union(unionNo, orderNos);
        //生成虚拟订单
        MallOrderEntity mallOrderEntity = new MallOrderEntity();
        mallOrderEntity.setUserId(userId);
        mallOrderEntity.setOrderNo(unionNo);
        mallOrderEntity.setPay(payPrice);
        return mallOrderEntity;
    }

    @Autowired
    private OrderUnionService orderUnionService;

    /**
     * 创建后台订单
     *
     * @return
     */
    private List<MallOrderEntity> buildSendOrder(Long fromUserId, Long toUserId, Integer orderType, String province, String city, String county, String detail, String userName, String mobile, String remark, List<OrderItemEntity> itemEntities) {
        List<MallOrderEntity> mallOrderEntities = new ArrayList<>();
        HashMap<Long, List<OrderItemEntity>> map = new HashMap<>();
        //把订单按照公司区分
        for (OrderItemEntity itemEntity : itemEntities) {
            Long shopUserId = mallGoodsDao.get(itemEntity.getGoodsId()).getUserId();
            if (shopUserId == null) { //默认是公司的
                shopUserId = Const.ADMIN_ID;
            }
            if (map.containsKey(shopUserId)) {
                map.get(shopUserId).add(itemEntity);
            } else {
                List<OrderItemEntity> list = new ArrayList<>();
                list.add(itemEntity);
                map.put(shopUserId, list);
            }
        }
        //分开组件订单
        for (Long shopId : map.keySet()) {
            MallOrderEntity orderEntity;
            Integer busType = MallOrderBusTypeEnum.SEND.getIndex();
            BigDecimal price = BigDecimal.ZERO;
            Integer quantity = 0;
            Integer orderStatus = MallOrderOrderStatusEnum.NEW.getIndex();
            BigDecimal logFee = BigDecimal.ZERO;
            //生成发货订单
            if (MallOrderOrderTypeEnum.DELIVERY.getIndex() == orderType) {
                orderEntity = new MallOrderEntity(createNO(fromUserId), fromUserId, orderType, busType, toUserId, price, quantity, new Date(), orderStatus, logFee, userName, mobile, province, city, county, detail, remark, MallOrderPayStatusEnum.PAID.getIndex(), shopId);
            } else { //转货订单
                // 转货是已经完成状态
                orderStatus = MallOrderOrderStatusEnum.DONE.getIndex();
                orderEntity = new MallOrderEntity(createNO(fromUserId), fromUserId, orderType, busType, toUserId, price, quantity, new Date(), orderStatus, remark, MallOrderPayStatusEnum.PAID.getIndex(), shopId);
            }
            mallOrderDao.save(orderEntity);
            buildOrderItem(orderEntity, map.get(shopId));
            mallOrderEntities.add(orderEntity);
        }

        return mallOrderEntities;
    }

    //创建还货订单
    private MallOrderEntity buildReturnOrder(Long userId, String name, String orderNo) {
        Integer busType = MallOrderBusTypeEnum.RETURN.getIndex();
        Integer orderType = MallOrderOrderTypeEnum.TRANSFER.getIndex();
        BigDecimal price = BigDecimal.ZERO;
        Integer quantity = 0;
        Integer orderStatus = MallOrderOrderStatusEnum.DONE.getIndex();
        String remark = name + Const.BUY_ORDER_NO + orderNo;
        MallOrderEntity orderEntity = new MallOrderEntity(createNO(userId), userId, orderType, busType, Const.ADMIN_ID, price, quantity, new Date(), orderStatus, remark, MallOrderPayStatusEnum.PAID.getIndex(), null);
        mallOrderDao.save(orderEntity);
        return orderEntity;
    }

    //创建自动购买订单
    private MallOrderEntity buildAutoBuyOrder(Long userId, String name, String orderNo) {
        Integer busType = MallOrderBusTypeEnum.AUTO_BUY.getIndex();
        Integer orderType = MallOrderOrderTypeEnum.TRANSFER.getIndex();
        BigDecimal price = BigDecimal.ZERO;
        Integer quantity = 0;
        Integer orderStatus = MallOrderOrderStatusEnum.DONE.getIndex();
        String remark = name + Const.BUY_ORDER_NO + orderNo;
        Integer payWay = MallOrderPayWayEnum.CASH.getIndex();
        Integer payStatus = MallOrderPayStatusEnum.PAID.getIndex();
        Integer mention = MallActRewardTypeEnum.no.getIndex();
        BigDecimal point = BigDecimal.ZERO;
        BigDecimal coupon = BigDecimal.ZERO;
        BigDecimal voucher = BigDecimal.ZERO;
        BigDecimal clear = BigDecimal.ZERO;
        MallOrderEntity orderEntity = new MallOrderEntity(createNO(userId), Const.ADMIN_ID, orderType, busType, payWay, userId, price, quantity, new Date(), new Date(), orderStatus, payStatus, point, coupon, voucher, remark, clear, mention, null);
        mallOrderDao.save(orderEntity);
        return orderEntity;
    }

    @Autowired
    private StoresService storesService;

    @Autowired
    private MallSkuDao mallSkuDao;

    @Autowired
    private LotteryRecordDao lotteryRecordDao;

    /**
     * 从购物车构建订单明细
     *
     * @param orderEntity
     * @param
     */
    private List<OrderItemEntity> buildOrderItem(MallOrderEntity orderEntity, List<? extends ItemVo> itemVos) {
        List<OrderItemEntity> orderItemEntities = new ArrayList<>();
        //总价格
        BigDecimal totalPrice = new BigDecimal(0);
        //总积分
        BigDecimal totalPoint = new BigDecimal(0);
        //总优惠券
        BigDecimal totalCoupon = new BigDecimal(0);
        //总换购券
        BigDecimal totalVocher = new BigDecimal(0);
        //总清货券
        BigDecimal totalClear = new BigDecimal(0);
        //总物流费
        BigDecimal totalLogFee = new BigDecimal(0);
        //总可使用抵扣卷
        BigDecimal totalCard = new BigDecimal(0);
        //总数量
        Integer totalQuantity = 0;
        String province = null;
        //生成订单明细
        for (ItemVo itemVo : itemVos) {
            MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(itemVo.getGoodsId());
            if (itemVo.getSkuName() != null) {
                MallSkuEntity sku = mallSkuDao.queryNameAndGoodsId(itemVo.getSkuName(), itemVo.getGoodsId());
                if (sku != null && sku.getNowPrice() != null) {
                    mallGoodsEntity.setNowPrice(sku.getNowPrice());
                }
            }
            TicketVo ticketVo = actService.getTicketVo(mallGoodsEntity.getId());
            OrderItemEntity orderItemEntity = new OrderItemEntity(orderEntity.getId(),
                    itemVo.getGoodsId(),
                    itemVo.getSkuName(),
                    mallGoodsEntity.getName(),
                    mallGoodsEntity.getNowPrice(),
                    mallGoodsEntity.getWeight(),
                    mallGoodsEntity.getImg(),
                    itemVo.getQuantity(),
                    ticketVo.getPoint(),
                    ticketVo.getCoupon(),
                    ticketVo.getVoucher(),
                    ticketVo.getClear());
//          判断是否是门店采购的产品已经该用户是不是线下门店的经营者
            StoresEntity stores = this.storesService.findByUserId(orderEntity.getUserId());
            LevelEntity levelEntity = this.levelDao.findByUserId(orderEntity.getUserId());

            if (mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.STORES.getIndex()) && (stores != null || levelEntity.getLv() <= 6)) {
                orderItemEntity.setPrice(mallGoodsEntity.getShopPrice());
            }
            Boolean flag = false;
            if (mallGoodsEntity.getSaleType() == MallGoodsSaleTypeEnum.AGENT.getIndex()||mallGoodsEntity.getSaleType() == MallGoodsSaleTypeEnum.DAY_SEL.getIndex()) {
                if (orderEntity.getBusType() == MallOrderBusTypeEnum.BUY.getIndex()) {
                    flag = true;
                }
            }
            //计算代理产品价格
            calculatePrice(orderEntity.getFromUserId(), orderEntity.getUserId(), orderItemEntity, flag);
            orderItemDao.save(orderItemEntity);
            orderItemEntities.add(orderItemEntity);
            //统计总金额
            totalPrice = totalPrice.add(orderItemEntity.getTotalPrice());
            //累计总积分
            totalPoint = totalPoint.add(orderItemEntity.getTotalPoint());
            //如果是库存发货订单 则不计算
            if (orderEntity.getOrderType() == MallOrderOrderTypeEnum.DELIVERY.getIndex() && orderEntity.getBusType() != MallOrderBusTypeEnum.SEND.getIndex()) {
                //累计总优惠券
                totalCoupon = totalCoupon.add(orderItemEntity.getTotalCoupon());
                //累计总换购券
                totalVocher = totalVocher.add(orderItemEntity.getTotalVoucher());
                //累计总清货券
                totalClear = totalClear.add(orderItemEntity.getTotalClear());

            }
            //计算可抵扣礼品卷
            if (mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.CARD.getIndex())) {
                totalCard = totalCard.add(orderItemEntity.getPrice().multiply(new BigDecimal(orderItemEntity.getQuantity())));
            }
         /*   //发货计算物流费
            if (orderEntity.getOrderType().equals(MallOrderOrderTypeEnum.DELIVERY.getIndex())) {
                BigDecimal logFee = computeLogFee(mallGoodsEntity, itemVo.getQuantity(), orderEntity.getProvince());
                totalLogFee = totalLogFee.add(logFee);
            }*/
            province = orderEntity.getProvince();
            //累计总数量
            totalQuantity += orderItemEntity.getQuantity();
        }

        //发货计算物流费
        if (orderEntity.getMention() == null) {
            orderEntity.setMention(MallActRewardTypeEnum.no.getIndex());
        }
        if (orderEntity.getOrderType().equals(MallOrderOrderTypeEnum.DELIVERY.getIndex()) && orderEntity.getMention().equals(MallActRewardTypeEnum.no.getIndex())) {
            BigDecimal logFee = computeLogFee(itemVos, province);
            totalLogFee = totalLogFee.add(logFee);

        }
        //更新订单 的总金额与可使用的优惠券
        orderEntity.setPrice(totalPrice);
        orderEntity.setPoint(totalPoint);
        orderEntity.setCoupon(totalCoupon);
        orderEntity.setVoucher(totalVocher);
        orderEntity.setQuantity(totalQuantity);
        orderEntity.setCard(totalCard);
        orderEntity.setLogFee(totalLogFee);
        mallOrderDao.update(orderEntity);
        return orderItemEntities;
    }

    //获取订单实际要支付的金额 加上物流费 减去所有抵扣券
    public BigDecimal getRetailPrice(MallOrderEntity orderEntity) {
        //如果需要物流费 加上物流费
        BigDecimal tem = orderEntity.getPrice();
        //如果优惠券可以抵扣
        if (orderEntity.getCoupon() != null && orderEntity.getCoupon().compareTo(BigDecimal.ZERO) > 0) {
            //优惠券抵扣价格
            tem = tem.subtract(orderEntity.getCoupon());
        }
        //换购券可以抵扣
        if (orderEntity.getVoucher() != null && orderEntity.getVoucher().compareTo(BigDecimal.ZERO) > 0) {
            //优惠券抵扣价格
            tem = tem.subtract(orderEntity.getVoucher());
        }
        //清货券可以抵扣
        if (orderEntity.getClear() != null && orderEntity.getClear().compareTo(BigDecimal.ZERO) > 0) {
            //优惠券抵扣价格
            tem = tem.subtract(orderEntity.getClear());
        }

        if (orderEntity.getCard() != null && orderEntity.getCard().compareTo(BigDecimal.ZERO) > 0) {
            tem = tem.subtract(orderEntity.getCard());
        }

        //收取邮费
        if (orderEntity.getLogFee() != null) {
            tem = tem.add(orderEntity.getLogFee());
        }
        if (tem.compareTo(BigDecimal.ZERO) < 0) {
            tem = BigDecimal.ZERO;
        }
        return tem;

    }

    @Autowired
    private SaleTypeInfoDao saleTypeInfoDao;


    /**
     * 计算店铺利润
     *
     * @param orderEntity
     * @return
     */
    public BigDecimal getShopProfit(MallOrderEntity orderEntity) {
        //如果需要物流费 加上物流费
        BigDecimal tem = BigDecimal.ZERO;

        //提货卡可以抵扣
        BigDecimal cardPrice = orderEntity.getCard();
        if (cardPrice.compareTo(BigDecimal.ZERO) > 0) {
            tem = tem.subtract(cardPrice);
        }
        //收取邮费
        if (orderEntity.getLogFee() != null) {
            tem = tem.add(orderEntity.getLogFee());
        }
        if (tem.compareTo(BigDecimal.ZERO) < 0) {
            tem = BigDecimal.ZERO;
        }
        List<OrderItemEntity> items = this.orderItemDao.findByOrderId(orderEntity.getId());
        for (OrderItemEntity item : items) {
            MallGoodsEntity mallGoodsEntity = this.mallGoodsDao.get(item.getGoodsId());
            BigDecimal price;
            BigDecimal decimal;
            //获取结算总金额
            if (mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.STORES.getIndex())) {
                price = mallGoodsEntity.getShopPrice(); //如果是门店采购 获取采购价
            } else if (mallGoodsEntity.getUserId() != null && !mallGoodsEntity.getUserId().equals(Const.ADMIN_ID) && (mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())||mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex()))) {
                price = mallGoodsEntity.getSupplyPrice();  //是代理有利 并且不是公司的 获取供货价
            } else {
                price = mallGoodsEntity.getNowPrice();  //获取现价
            }
            decimal = price;
            //  MallActEntity mallActEntity = this.mallActDao.findByGoodsIdAndstatus(mallGoodsEntity.getId(), MallActStatusEnum.OPEN.getIndex());
            // 获取售卖类型信息 扣除券的奖励
            SaleTypeInfoEntity saleTypeInfoEntity = saleTypeInfoDao.findByGoodsId(mallGoodsEntity.getId());
            if (saleTypeInfoEntity != null) {
                //扣除区域奖励
                if (saleTypeInfoEntity.getAreaReward() != null && saleTypeInfoEntity.getAreaReward().contains("_")) {
                    //如果不是代理有利的产品才扣除区域
                    if (!mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())&&!mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex())) {
                        String[] areas = saleTypeInfoEntity.getAreaReward().split("_");
                        for (String area : areas) {
                            price = price.subtract(new BigDecimal(area).multiply(decimal).divide(new BigDecimal(1000)));
                        }
                    }
                }
                //扣除换购券奖励
                if (saleTypeInfoEntity.getVoucherReward() != null && saleTypeInfoEntity.getVoucherReward().contains("_")) {
                    String[] vouchers = saleTypeInfoEntity.getVoucherReward().split("_");
                    for (String voucher : vouchers) {
                        price = price.subtract(new BigDecimal(voucher));
                    }
                }
                //扣除现金券奖励
                if (saleTypeInfoEntity.getCashReward() != null && saleTypeInfoEntity.getCashReward().contains("_")) {
                    String[] cashs = saleTypeInfoEntity.getCashReward().split("_");
                    for (String cash : cashs) {
                        price = price.subtract(new BigDecimal(cash));
                    }
                }
                // //扣除清货券奖励
                if (saleTypeInfoEntity.getClearReward() != null && saleTypeInfoEntity.getClearReward().contains("_")) {
                    String[] clears = saleTypeInfoEntity.getClearReward().split("_");
                    for (String clear : clears) {
                        price = price.subtract(new BigDecimal(clear));
                    }
                }
                // //扣除优惠券奖励
                if (saleTypeInfoEntity.getCouponReward() != null && saleTypeInfoEntity.getCouponReward().contains("_")) {
                    String[] coupons = saleTypeInfoEntity.getCouponReward().split("_");
                    for (String coupon : coupons) {
                        price = price.subtract(new BigDecimal(coupon));
                    }
                }
                // //扣除可使用清货券
                if (saleTypeInfoEntity.getMaxClear() != null) {
                    price = price.subtract(saleTypeInfoEntity.getMaxClear());
                }
                //扣除可使用优惠券
                if (saleTypeInfoEntity.getMaxCoupon() != null) {
                    price = price.subtract(saleTypeInfoEntity.getMaxCoupon());
                }
                //扣除可使用换购券
                if (saleTypeInfoEntity.getMaxVoucher() != null) {
                    price = price.subtract(saleTypeInfoEntity.getMaxVoucher());
                }
            }
            tem = tem.add(price.multiply(new BigDecimal(item.getQuantity())));
        }
        //扣除店铺管理费
        tem = tem.subtract(getManagerProfit(orderEntity, false)).subtract(new BigDecimal(orderEntity.getQuantity() * 0.1));
        return tem;

    }

    /**
     * 获取管理利润
     *
     * @return
     */
    BigDecimal getManagerProfit(MallOrderEntity orderEntity, Boolean flag) {
        List<OrderItemEntity> orderItemEntities = orderItemDao.findByOrderId(orderEntity.getId());
        BigDecimal total = BigDecimal.ZERO;
        for (OrderItemEntity itemEntity : orderItemEntities) {
            MallGoodsEntity mallGoodsEntity = this.mallGoodsDao.get(itemEntity.getGoodsId());
            // MallActEntity actEntity = actService.findByGoodsIdAndstatus(itemEntity.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
            SaleTypeInfoEntity saleTypeInfoEntity = saleTypeInfoDao.findByGoodsId(itemEntity.getGoodsId());
            BigDecimal tem = BigDecimal.ZERO;
            if (saleTypeInfoEntity != null && saleTypeInfoEntity.getManagerReward() != null && !saleTypeInfoEntity.getManagerReward().equals("")) {
                if (mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.STORES.getIndex())) {
                    tem = tem.add(new BigDecimal(saleTypeInfoEntity.getManagerReward()).multiply(mallGoodsEntity.getShopPrice()));
                } else if (mallGoodsEntity.getUserId() != null && !mallGoodsEntity.getUserId().equals(Const.ADMIN_ID) && (mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())||mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex()))) {
                    //如果是true则是给予管理费 否则就是结算店铺利润不扣除管理费
                    if (flag) {
                        tem = tem.add(new BigDecimal(saleTypeInfoEntity.getManagerReward()).multiply(mallGoodsEntity.getSupplyPrice()));
                    } else {
                        tem = BigDecimal.ZERO;
                    }
                } else {
                    tem = tem.add(new BigDecimal(saleTypeInfoEntity.getManagerReward()).multiply(mallGoodsEntity.getNowPrice()));
                }
            }
            tem = tem.multiply(new BigDecimal(itemEntity.getQuantity()));
            total = total.add(tem);
        }
        return total;
    }

    //通知入库
    void noticeOrder(MallOrderEntity orderEntity) {
        List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(orderEntity.getId());
        StringBuffer sb = new StringBuffer();
        itemEntities.forEach(orderItemEntity -> {
            sb.append(orderItemEntity.getName() + "X" + orderItemEntity.getQuantity());
        });
        UserEntity user = userDao.get(orderEntity.getUserId());
        UserEntity fromUser = userDao.get(orderEntity.getFromUserId());
        UserEntity topUser = userDao.get(user.getPid());
        //转货 发送入库通知给本人 发送出库通知给转出人
        if (orderEntity.getOrderType().equals(MallOrderOrderTypeEnum.TRANSFER.getIndex())) {
            noticeService.sendOrderIn(user.getOpenId(), user.getName(), sb.toString());
            noticeService.sendOrderOut(fromUser.getOpenId(), orderEntity.getOrderNo(), sb.toString());
        }

//        LevelEntity level = levelDao.findByUserId(user.getId());
//        if (level.getName().contains("联盟")) {
//            return;
//        }

        //商城下单 通知上级与推荐人
        if (topUser != null && orderEntity.getBusType().equals(MallOrderBusTypeEnum.BUY.getIndex())) {
            if (!fromUser.getId().equals(Const.ADMIN_ID)) {
                noticeService.sendNewOrder(fromUser.getOpenId(), orderEntity.getOrderNo(), sb.toString());
            }
            noticeService.sendOrderDone(topUser.getOpenId(), user.getName(), sb.toString(), MallOrderPayWayEnum.indexOf(orderEntity.getPayWay()), orderEntity.getPrice());
            //推荐人另有其人
            if (!user.getRid().equals(user.getPid())) {
                UserEntity referUser = userDao.get(user.getRid());
                noticeService.sendOrderDone(referUser.getOpenId(), user.getName(), sb.toString(), MallOrderPayWayEnum.indexOf(orderEntity.getPayWay()), orderEntity.getPrice());
            }
        }

        if(orderEntity.getShareId()!=null&&!topUser.getId().equals(orderEntity.getShareId())&&!orderEntity.getShareId().equals(orderEntity.getUserId())){
            UserEntity tem = userDao.get(orderEntity.getShareId());
            noticeService.sendOrderDone(tem.getOpenId(), user.getName(), sb.toString(), MallOrderPayWayEnum.indexOf(orderEntity.getPayWay()), orderEntity.getPrice());
        }

        if(orderEntity.getTeamId()!=null&&!topUser.getId().equals(orderEntity.getTeamId())&&!orderEntity.getTeamId().equals(orderEntity.getUserId())){
            UserEntity tem = userDao.get(orderEntity.getTeamId());
            noticeService.sendOrderDone(tem.getOpenId(), user.getName(), sb.toString(), MallOrderPayWayEnum.indexOf(orderEntity.getPayWay()), orderEntity.getPrice());
        }
    }

    @Autowired
    private NoticeService noticeService;


    @Autowired
    private WxPayService wxPayService;


    //统一下单
    @Override
    public String unionOrder(MallOrderEntity mallOrderEntity, String noticeUrl) {
        BigDecimal decimal = mallOrderEntity.getPay();
        if (decimal == null) {
            decimal = getRetailPrice(mallOrderEntity);
        }
        //如果不用付钱
        if (decimal.compareTo(BigDecimal.ZERO) == 0) {
            afterPayOrder(mallOrderEntity.getOrderNo());
            return "ZERO";
        }
       /* //修改库存 que
        updateStock(mallOrderEntity);*/

        UserEntity userEntity = userDao.get(mallOrderEntity.getUserId());
        return wxPayService.createWebConfig(mallOrderEntity.getOrderNo(), decimal.doubleValue(), "购买产品", userEntity.getOpenId(), noticeUrl);
    }


    /**
     * 商城下单的单走此验证
     * 是否禁止转货 是否可以发货
     * 商城购买的 下架产品不能购买
     * 活动未开始不能下单  积分不够不能下单  提货卡活动、限购级别、限购数量、限购捆绑销售
     * 是否限制支付
     *
     * @param
     * @param recordId
     */
    private void validateCommitOrder(List<? extends ItemVo> itemVos, Integer orderType, Long userId, String remark, AddressEntity address, Integer temp, Long recordId, Integer payWay,Long shareId) {
        BigDecimal voucher = BigDecimal.ZERO;
        Map<Long, Integer> map = new HashMap<>();
        LevelEntity levelEntity = levelDao.findByUserId(userId);
        for (ItemVo itemVo : itemVos) {
            MallGoodsEntity goodsEntity = mallGoodsDao.get(itemVo.getGoodsId());
            if(goodsEntity.getName().contains("团品")){
                if(shareId==null){
                    throw new RRException("需从分享链接购买团品");
                }
                if(shareId.equals(userId)){
                    throw new RRException("请勿购买自己的分享!");
                }
            }
            if(goodsEntity.getVipLevel()!=null){
                if(goodsEntity.getVipLevel().contains(levelEntity.getName())){
                    throw new RRException("请向供货商进货!");
                }
            }
            if (MallGoodsShelfEnum.ON.getIndex() != goodsEntity.getShelf()) {
                throw new RRException(goodsEntity.getName() + "已经下架!");
            }
            //产品跟级别都是限制状态 限制微信支付
            if (payWay == MallOrderPayWayEnum.WX.getIndex() && goodsEntity.getLimitPayWay() != null && 1 == goodsEntity.getLimitPayWay() && levelEntity.getLimitPayWay() != null && levelEntity.getLimitPayWay() == 1) {
                throw new RRException("请用代金券支付!");
            }
            //如果是自提 则需判断产品是否可以自提
            if (temp != null && temp == 1) {
                boolean flag = false;
                if (goodsEntity.getUserId() != null) {
                    //只有智慧门店才能自提
                    ShopEntity shopEntity = shopDao.findByUserId(goodsEntity.getUserId());
                    //判断是否为自提门店
                    if (shopEntity.getType() == ShopTypeEnum.ONE.getIndex()) {
                        flag = true;
                    }
                }
                if (goodsEntity.getUserId() == null || goodsEntity.getUserId().equals(Const.ADMIN_ID) || !flag) {
                    throw new RRException(goodsEntity.getName() + "是非自提的产品");
                }
            } else {
                //如果不是自提 判断地址是否为空
                if (address.getProvince() == null || "".equals(address.getProvince())) {
                    throw new RRException("请选择快递地址");
                }
            }
            MallActEntity actEntity = mallActDao.findByGoodsIdAndstatus(itemVo.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
            if (actEntity != null && actEntity.getBindGoodsId() != null) {
                Integer number = map.get(actEntity.getBindGoodsId());
                if (number != null) {
                    map.put(actEntity.getBindGoodsId(), number + 1);
                } else {
                    map.put(actEntity.getBindGoodsId(), 1);
                }
            }
            //存在活动查看活动存在的一些限制
            actService.validateCommit(userId, remark, itemVo, itemVos, orderType, recordId);
            BigDecimal voucherPrice = validateVoucher(itemVo);
            if (voucherPrice.compareTo(BigDecimal.ZERO) > 0) {
                voucher = voucher.add(voucherPrice);
            }
        }
        for (Long key : map.keySet()) {
            if (map.get(key) >= 2) {
                throw new RRException("存在多个捆绑活动不能组合下单");
            }
        }
        // 如果是换购有利的产品 必须换购券余额足够才能购买
//        if (voucher.compareTo(BigDecimal.ZERO) > 0) {
//            AccountEntity accountEntity = accountService.findByUserIdAndType(userId, AccountTypeEnum.VOUCHER.getIndex());
//            if (accountEntity == null || voucher.compareTo(accountEntity.getAmount()) > 0) {
//                throw new RRException("换购产品只能换购券购买");
//            }
//        }
    }

    private BigDecimal validateVoucher(ItemVo itemVo) {
        SaleTypeInfoEntity saleTypeInfoEntity = saleTypeInfoDao.findByGoodsId(itemVo.getGoodsId());

        if (saleTypeInfoEntity.getMaxVoucher() != null) {
            return saleTypeInfoEntity.getMaxVoucher();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 验证后台转货发货
     */
    private void validateSendOrder(List<? extends ItemVo> itemVos, Long fromUserId, Long toUserId, Integer orderType) {
        for (ItemVo itemVo : itemVos) {
            actService.validateSend(itemVo, orderType, fromUserId, toUserId);
        }
    }


    @Autowired
    private MallActDao mallActDao;


    @Override
    public void payment(String orderNo, Long userId) {
        MallOrderEntity orderEntity = mallOrderDao.findByOrderNo(orderNo.trim());
        if (orderEntity == null) {
            throw new RRException("订单不存在!");
        }
        UserEntity userEntity = userDao.get(orderEntity.getUserId());
        //级别高的上级
        // UserEntity topUser = userService.getLvTopUser(userEntity.getId());
        UserEntity topUser = userDao.get(userId);
        List<OrderItemEntity> orderItemEntities = orderItemDao.findByOrderId(orderEntity.getId());
        //需要进货的
        List<OrderItemEntity> needBuyItems = new ArrayList<>();
        //需要还货的
        List<OrderItemEntity> needBackItems = new ArrayList<>();
        for (OrderItemEntity item : orderItemEntities) {
            //非代理产品跳过
            MallGoodsEntity goodsEntity = mallGoodsDao.get(item.getGoodsId());
            if (!goodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())&&!goodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex())) {
                continue;
            }
            //判断价格
            PriceEntity topUserPrice = priceService.findByUserIdAndGoodsIdAndCode(topUser.getId(), item.getGoodsId(), topUser.getTCode());
            PriceEntity userPrice = priceService.findByUserIdAndGoodsIdAndCode(userEntity.getId(), item.getGoodsId(), userEntity.getTCode());
            BigDecimal tem = userPrice.getPrice().subtract(topUserPrice.getPrice()).multiply(new BigDecimal(item.getQuantity()));
            //无收款的产品 我的进货价不于购买人的价格
            if (tem.compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }
            OrderItemEntity orderItemEntity = new OrderItemEntity(orderEntity.getId(), item.getGoodsId(), null, item.getName(), userPrice.getPrice(), item.getWeight(), item.getImg(), null, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
            //判断库存是否充足
            MallStoreEntity storeEntity = mallStoreDao.findByUserIdAndGoodsId(topUser.getId(), item.getGoodsId());
            //库存充足  还货
            if (storeEntity != null && storeEntity.getQuantity() >= item.getQuantity()) {
                orderItemEntity.setQuantity(item.getQuantity());
                //加入还货
                needBackItems.add(orderItemEntity);
                continue;
            }
            //库存不足 足的地方还了  不足的地方补
            Integer temQ = item.getQuantity();
            if (storeEntity != null && storeEntity.getQuantity() > 0) {
                temQ = item.getQuantity() - storeEntity.getQuantity();
                //需要补的
                OrderItemEntity temItem = new OrderItemEntity(orderEntity.getId(), item.getGoodsId(), null, item.getName(), userPrice.getPrice(), item.getWeight(), item.getImg(), storeEntity.getQuantity(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
                needBackItems.add(temItem);
            }
            //需要买的
            orderItemEntity.setQuantity(temQ);
            needBuyItems.add(orderItemEntity);
        }
        //还货
        if (needBackItems.size() > 0) {
            autoBack(topUser.getId(), needBackItems, userEntity.getName(), orderNo);
        }
        //补货
        if (needBuyItems.size() > 0) {
            autoBuy(topUser.getId(), needBuyItems, userEntity.getName(), orderNo);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void equalLevel(Long userId, String orderNO) {
        MallOrderEntity orderEntity = mallOrderDao.findByOrderNo(orderNO);
        if (orderEntity == null) {
            throw new RRException("订单不存在!");
        }
        //找出上面所有平级
        UserEntity temUser = userDao.get(orderEntity.getUserId());
        Long buyUserId = temUser.getId();
        String buUserName = temUser.getName();
        LevelEntity level = levelDao.get(temUser.getLevelId());
        List<UserEntity> parents = new ArrayList<>();
        while (temUser != null) {
            //没有上级
            if (temUser.getPid() == null || temUser.getPid().equals(Const.ADMIN_ID)) {//没有上级了
                break;
            }
            UserEntity parent = userDao.get(temUser.getPid());
            LevelEntity temLevel = levelDao.get(parent.getLevelId());
            if (temLevel.getLv().equals(level.getLv())) { //如果上面的级别低或者相等
                parents.add(parent);
            } else if (temLevel.getLv()<level.getLv()){ //出现高级别的就中断
                break;
            }
            temUser = parent;
        }
        //没有平级直接跳过
        if (parents.size() == 0) {
            return;
        }
        //汇总每个产品的利润
        List<OrderItemEntity> items = orderItemDao.findByOrderId(orderEntity.getId());
        UserEntity user = userDao.get(userId);
        for (OrderItemEntity item : items) {
            PriceEntity priceEntity = priceService.findByUserIdAndGoodsIdAndCode(buyUserId, item.getGoodsId(), user.getTCode());
            if (priceEntity == null) {
                continue;
            }
            String profit = priceEntity.getProfit();
            if (profit == null || profit.equals("") || profit.equals("0")) {
                continue;
            }
            //利润
            List<String> profits = Arrays.asList(profit.split("_"));
            for (int i = 0; i < profits.size(); i++) {
                //利润X数量
                BigDecimal amount = new BigDecimal(profits.get(i)).multiply(new BigDecimal(item.getQuantity()));
                UserEntity temParent;
                if (i < parents.size()) {
                    temParent = parents.get(i);
                } else {//上面没有人了  全部累计给最上面的人 不累计了
//                    temParent = parents.get(parents.size() - 1);
                    break;
                }
                temParent.setTemProfit(temParent.getTemProfit().add(amount));
            }
        }
        //给出利润
        for (UserEntity parent : parents) {
            accountService.transfer(userId, parent.getId(), AccountTypeEnum.CASH.getIndex(), parent.getTemProfit(), "平级利润" + buUserName + Const.BUY_ORDER_NO + orderNO);
        }
    }

    @Override
    public void vipProfit(Long userId, String orderNO) {
        MallOrderEntity orderEntity = mallOrderDao.findByOrderNo(orderNO);
        UserEntity user = userDao.get(userId);
        if (orderEntity.getVipUserId() == null) return;
        List<OrderItemEntity> items = orderItemDao.findByOrderId(orderEntity.getId());
        BigDecimal total = BigDecimal.ZERO;
        UserEntity buyUser = userDao.get(orderEntity.getUserId());
        for (OrderItemEntity item : items) {
            if (isVip(item.getGoodsId(), buyUser.getId(), buyUser.getTCode())) {//如果是VIP
                PriceEntity priceEntity = priceService.findByUserIdAndGoodsIdAndCode(buyUser.getId(), item.getGoodsId(), buyUser.getTCode());
                total = total.add(new BigDecimal(item.getQuantity()).multiply(priceEntity.getVipProfit()));
            }
        }
        if (total.compareTo(BigDecimal.ZERO) > 0) {
            accountService.transfer(userId, orderEntity.getVipUserId(), AccountTypeEnum.CASH.getIndex(), total, "负责人利润" + buyUser.getName() + Const.BUY_ORDER_NO + orderNO);
        }
    }

    /**
     * 库存够的时候 直接把货还给公司即可 拿全款
     *
     * @param userId
     * @param items
     */
    void autoBack(Long userId, List<OrderItemEntity> items, String name, String orderNo) {
        //生成订单
        MallOrderEntity orderEntity = buildReturnOrder(userId, name, orderNo);
        //生成明细
        buildOrderItem(orderEntity, items);
        //转货
        mallStoreService.transfer(orderEntity.getId());
    }

    //自动购买业务 但是库存不给
    void autoBuy(Long userId, List<OrderItemEntity> items, String name, String orderNo) {
        //生成订单
        MallOrderEntity orderEntity = buildAutoBuyOrder(userId, name, orderNo);
        //生成明细
        buildOrderItem(orderEntity, items);
        //扣钱
        accountService.autoPay(userId, AccountTypeEnum.CASH.getIndex(), orderEntity.getPrice(), orderEntity.getOrderNo());
        //生成代收款
        codOrder(orderEntity);
        //计算平级
        LevelEntity temLevel = levelDao.findByUserId(userId);
        if (temLevel.getName().contains("联盟")) { //联盟下单直接结算平级利润
            equalLevel(Const.ADMIN_ID, orderEntity.getOrderNo());
            vipProfit(Const.ADMIN_ID, orderEntity.getOrderNo());
        }
        //送经验值
        accountService.rewardExp(userId, orderEntity.getPrice(), orderNo, name, true);
        accountService.rewardEqlExp(userId, orderEntity.getPrice(), orderNo, name, true);
    }

    @Autowired
    private MallStoreDao mallStoreDao;

    //不计算联盟的
//    void equalProfit(MallOrderEntity mallOrderEntity) {
//        List<UserProfit> userProfits = calProfit(mallOrderEntity, 0);
//        for (int i = 0; i < userProfits.size(); i++) {
//            UserProfit userProfit = userProfits.get(i);
//            //生成代收款
//            AccountRecordEntity record = new AccountRecordEntity(Const.ADMIN_ID, userProfit.getId(), AccountTypeEnum.CASH.getIndex(), userProfit.getAmount(), null, null, new Date(), userProfit.getBuyName() + Const.BUY_ORDER_NO + mallOrderEntity.getOrderNo(), AccountRecordStatusEnum.WAIT.getIndex(), AccountRecordBusEnum.LEVEL_PROFIT.getIndex());
//            accountRecordDao.save(record);
//        }
//    }


    //下载折让数据
    @Override
    public void downProfit(MallOrderEntity param, HttpServletResponse response) {
        if (param.getOrderTimes() == null) {
            throw new RRException("请选择订单时间");
        }
        if (param.getOrderTimes()[1].getMonth() == new Date().getMonth() || param.getOrderTimes()[0].getMonth() == new Date().getMonth()) {
            throw new RRException("请选择上个月");
        }
        List<ProfitDown> profitDowns = mallGoodsDao.downProfit(param.getOrderTimes()[0], param.getOrderTimes()[1]);
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
        try {
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "折让").head(ProfitDown.class).build();
            excelWriter.write(profitDowns, writeSheet1);
            excelWriter.finish();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void downAccount(HttpServletResponse response) {
        List<AccountDown> datas = mallGoodsDao.downAccount();
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
        try {
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "折让").head(AccountDown.class).build();
            excelWriter.write(datas, writeSheet1);
            excelWriter.finish();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void downStore(HttpServletResponse response) {
        List<StoreDown> datas = mallGoodsDao.downStore();
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
        try {
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "折让").head(StoreDown.class).build();
            excelWriter.write(datas, writeSheet1);
            excelWriter.finish();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void downSale(HttpServletResponse response, String code,Date startDate,Date endDate) {
        if (endDate.getMonth() == new Date().getMonth() || startDate.getMonth() == new Date().getMonth()) {
            throw new RRException("请选择上个月");
        }
       List<SaleDown> saleDowns = mallOrderDao.downSale(code,startDate, endDate);
        try {
            ExcelWriter writer = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet sheet = EasyExcel.writerSheet(0,"明细").head(SaleDown.class).build();
            writer.write(saleDowns,sheet);
            sheet = EasyExcel.writerSheet(1,"汇总").head(SaleSumDown.class).build();
            writer.write(sumSale(saleDowns),sheet);
            writer.finish();
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    List<SaleSumDown> sumSale(List<SaleDown> saleDowns){
        Map<String,SaleSumDown> map = new HashMap<>();
        saleDowns.forEach(saleDown -> {
            SaleSumDown saleSumDown = new SaleSumDown(saleDown.getGoods(),0);
            if(map.containsKey(saleDown.getName())){
                saleSumDown = map.get(saleDown.getName());
            }
            saleSumDown.add(saleDown.getQuantity());
            map.put(saleSumDown.getName(),saleSumDown);
        });
        return map.values().stream().collect(Collectors.toList());
    }


    //    //    下载联盟的利润
//    public void downLevelProfit(List<MallOrderEntity> list, HttpServletResponse response) {
//        List<UserProfit> res = new ArrayList<>();
//        for (MallOrderEntity orderEntity : list) {
//            //只计算进货与自动进货
//            if (!orderEntity.getBusType().equals(MallOrderBusTypeEnum.BUY.getIndex()) && !orderEntity.getBusType().equals(MallOrderBusTypeEnum.AUTO_BUY.getIndex())) {
//                continue;
//            }
//            List<UserProfit> userProfits = calProfit(orderEntity);
//            res.addAll(userProfits);
//        }
//        Map<Long, UserProfit> map = new HashMap<>();
//        for (UserProfit userProfit : res) {
//            Long userId = userProfit.getId();
//            if (map.containsKey(userId)) {
//                UserProfit tem = map.get(userId);
//                tem.setAmount(tem.getAmount().add(userProfit.getAmount()));
//                if (!tem.getOrderNo().contains(userProfit.getOrderNo())) {
//                    tem.setOrderNo(tem.getOrderNo() + "," + userProfit.getOrderNo());
//                }
//                map.put(userId, tem);
//            } else {
//                map.put(userId, userProfit);
//            }
//        }
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
//        try {
//            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
//            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "折让").head(UserProfit.class).build();
//            excelWriter.write(new ArrayList(map.values()), writeSheet1);
//            excelWriter.finish();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

//    //领导人利润计算
//    List<UserProfit> calProfit(MallOrderEntity mallOrderEntity) {
//        List<UserProfit> userProfits = new ArrayList<>();
//        UserEntity userEntity = userDao.get(mallOrderEntity.getUserId());
//        //公司不处理
////        if (userEntity.getPid().equals(Const.ADMIN_ID)) {
////            return userProfits;
////        }
//        //只需要联盟购买的
//        LevelEntity levelEntity = levelDao.findByUserId(userEntity.getId());
//        if (!levelEntity.getName().contains("联盟单位")) {
//            return userProfits;
//        }
//        //领导人利润
//        List<OrderItemEntity> items = orderItemDao.findByOrderId(mallOrderEntity.getId());
//        for (OrderItemEntity item : items) {
//            MallGoodsEntity mallGoods = mallGoodsDao.get(item.getGoodsId());
//            //跳过没有利润的
//            if (mallGoods.getProfit() == null || mallGoods.getProfit().equals("") || mallGoods.getProfit().compareTo(BigDecimal.ZERO) <= 0) {
//                continue;
//            }
//
//            //找到第一个领导人 生成领导人利润
//            UserEntity leader = userService.findLeader(userEntity.getId());
//            if (leader != null) {
//                UserProfit profit = new UserProfit(leader.getId(), leader.getName(), leader.getCode(), mallGoods.getProfit().multiply(new BigDecimal(item.getQuantity())), mallOrderEntity.getOrderNo(), userEntity.getName());
//                userProfits.add(profit);
//            }
//        }
//        return userProfits;
//    }


    /**
     * 对进货订单进行代收款业务
     *
     * @param mallOrderEntity
     */
    void codOrder(MallOrderEntity mallOrderEntity) {
        UserEntity userEntity = userDao.get(mallOrderEntity.getUserId());
        //公司不处理
        if (userEntity.getPid().equals(Const.ADMIN_ID)) {
            return;
        }
        //级别高的上级
        UserEntity topUser = userService.getLvTopUser(userEntity.getId());
        //级别判断
        LevelEntity topUserLevel = levelDao.get(topUser.getLevelId());
        LevelEntity userLevel = levelDao.get(userEntity.getLevelId());
        //购买者级别要小于上级级别
        if (userLevel.getLv() < topUserLevel.getLv()) {
            return;
        }
        //开始计算价格
        BigDecimal total = BigDecimal.ZERO;
        List<OrderItemEntity> items = orderItemDao.findByOrderId(mallOrderEntity.getId());
        for (OrderItemEntity item : items) {
            MallGoodsEntity mallGoods = mallGoodsDao.get(item.getGoodsId());
            //零售产品跳过
            if (!mallGoods.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())&&!mallGoods.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex())) {
                continue;
            }
            PriceEntity topUserPrice = priceService.findByUserIdAndGoodsIdAndCode(topUser.getId(), item.getGoodsId(), topUser.getTCode());
            PriceEntity userPrice = priceService.findByUserIdAndGoodsIdAndCode(userEntity.getId(), item.getGoodsId(), userEntity.getTCode());
            BigDecimal tem = userPrice.getPrice().subtract(topUserPrice.getPrice()).multiply(new BigDecimal(item.getQuantity()));
            //有差价再显示
            if (tem.compareTo(BigDecimal.ZERO) > 0) {
                total = total.add(userPrice.getPrice().multiply(new BigDecimal(item.getQuantity())));
            }
        }
        //没有差价返回
        if (total.compareTo(BigDecimal.ZERO) < 1) {
            return;
        }
        //生成代收款
        AccountRecordEntity record = new AccountRecordEntity(Const.ADMIN_ID, topUser.getId(), AccountTypeEnum.CASH.getIndex(), total, null, null, new Date(), userEntity.getName() + Const.BUY_ORDER_NO + mallOrderEntity.getOrderNo(), AccountRecordStatusEnum.WAIT.getIndex(), AccountRecordBusEnum.PAYMENT.getIndex());
        accountRecordDao.save(record);

    }

    @Autowired
    private TeamSaleService teamSaleService;


    @Autowired
    private AccountService accountService;

    @Autowired
    private AccountRecordDao accountRecordDao;

    //账户支付
    void payByAccount(MallOrderEntity orderEntity) {
        //获取实际要支付的费用
        BigDecimal tem = getRetailPrice(orderEntity);
        if (tem.compareTo(BigDecimal.ZERO) > 0) {
            //给公司转账
            accountService.pay(orderEntity.getUserId(), AccountTypeEnum.CASH.getIndex(), tem, orderEntity.getOrderNo());
        }
        afterPayOrder(orderEntity);
        return;
    }

    //账户支付
    void payByAccount(List<MallOrderEntity> orderEntitys) {
        Map<String, Object> map = new HashMap<>();
        for (MallOrderEntity orderEntity : orderEntitys) {
            payByAccount(orderEntity);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payByWx(String orderNo) {
        afterPayOrder(orderNo);
    }

    //商城进货支付完成后
    public void afterPayOrder(MallOrderEntity orderEntity) {
        //已经支付
        if (orderEntity == null || orderEntity.getPayStatus().equals(MallOrderPayStatusEnum.PAID.getIndex())) {
            return;
        }
        mallStoreService.transfer(orderEntity.getId());
        //转货就已经完成了
        if (orderEntity.getOrderType().equals(MallOrderOrderTypeEnum.TRANSFER.getIndex())) {
            orderEntity.setOrderStatus(MallOrderOrderStatusEnum.DONE.getIndex());
        }
        //设置支付状态
        orderEntity.setPayStatus(MallOrderPayStatusEnum.PAID.getIndex());
        orderEntity.setPayTime(new Date());
        mallOrderDao.update(orderEntity);
        sendGroupProfit(orderEntity);
        //代收款 不再有代收款
//        codOrder(orderEntity);
        //活动逻辑
//        actService.fire(orderEntity);
        String name = userDao.get(orderEntity.getUserId()).getName();
        //结算店铺利润 第三方店铺发货
        if (!orderEntity.getFromUserId().equals(Const.ADMIN_ID) && !orderEntity.getOrderType().equals(MallOrderOrderTypeEnum.TRANSFER.getIndex())) {
            accountService.shopProfit(orderEntity.getFromUserId(), getShopProfit(orderEntity), name, orderEntity.getOrderNo());
        }
        //结算店铺管理利润 第三方店铺
        if (!orderEntity.getFromUserId().equals(Const.ADMIN_ID)) {
            accountService.shopManager(orderEntity.getFromUserId(), getManagerProfit(orderEntity, true), name, orderEntity.getOrderNo());
        }
//        addShare(orderEntity);
        //结算平级利润 暂时不结算
//        LevelEntity temLevel = levelDao.findByUserId(orderEntity.getUserId());
//        if (temLevel.getName().contains("联盟" )) { //联盟下单直接结算平级利润
//            equalLevel(Const.ADMIN_ID, orderEntity.getOrderNo());
//            vipProfit(Const.ADMIN_ID,orderEntity.getOrderNo());
//        }
//        activeLevel(orderEntity.getUserId());
        //通知
        noticeOrder(orderEntity);
        //TODO 捐赠通知
        noticeWelFare(orderEntity);
    }

    @Autowired
    private GoodsGroupDao goodsGroupDao;

    public void sendGroupProfit(MallOrderEntity orderEntity){
        List<OrderItemEntity> items = orderItemDao.findByOrderId(orderEntity.getId());
        for (OrderItemEntity item:items){
            if(orderEntity.getTeamId()==null){
                continue;
            }
            GoodsGroupEntity group = goodsGroupDao.findByUserIdAndGoodsId(orderEntity.getTeamId(),item.getGoodsId());
            if(group==null){
                continue;
            }
            UserEntity user = userDao.get(orderEntity.getUserId());
            BigDecimal teamAmount = group.getTeamProfit().multiply(new BigDecimal(item.getQuantity()));
            BigDecimal shareAmount = group.getShareProfit().multiply(new BigDecimal(item.getQuantity()));
            //团购奖励立即返利
            accountService.reward(orderEntity.getTeamId(),AccountTypeEnum.CASH.getIndex(),teamAmount,user.getName(),orderEntity.getOrderNo(),true,AccountRecordBusEnum.SHARE_REWARD.getIndex());
            if(orderEntity.getShareId()!=null){
                accountService.reward(orderEntity.getShareId(),AccountTypeEnum.CASH.getIndex(),shareAmount,user.getName(),orderEntity.getOrderNo(),true,AccountRecordBusEnum.SHARE_REWARD.getIndex());
            }
        }
    }

    @Autowired
    private MonthShareService shareService;

    @Autowired
    private MonthShareDao monthShareDao;

    //支付成功后添加月销
    //只有分享有利
//    void addShare(MallOrderEntity orderEntity){
//        //添加自己的
//        MonthShareEntity shareEntity = new MonthShareEntity(orderEntity.getUserId(),orderEntity.getQuantity(),orderEntity.getOrderNo(),new Date());
//        shareService.save(shareEntity);
//        //如果购买者是本月新增的 且月销没有任何购买者的记录 就是新人
//        UserEntity user = userDao.get(orderEntity.getUserId());
//        if(user.getTime().getMonth()==new Date().getMonth()){
//            //查找月销记录
//            List<MonthShareEntity> ses = monthShareDao.findByUser(user.getId(),null);
//            if(ses.size()<=1&&!user.getPid().equals(Const.ADMIN_ID)){
//                shareEntity = new MonthShareEntity(user.getPid(),orderEntity.getQuantity(),orderEntity.getOrderNo(),new Date());
//                monthShareDao.save(shareEntity);
//            }
//        }
//    }

    //取消移除月销
    void removeShare(String orderNO) {
        monthShareDao.removeByOrderNo(orderNO);
    }


    //取消移除业绩
    void removeSale(String orderNO) {
        teamSaleDao.remove(orderNO);
    }

    @Autowired
    private TeamSaleDao teamSaleDao;


    //任意买一单
    private void activeLevel(Long userId) {
        UserEntity user = userDao.get(userId);
        //自动升级市代
        LevelEntity level = levelDao.get(user.getLevelId());
        if (level.getLv() > 7) { //级别小于市代
            user.setLevelId(47L);//设置为市代
            userDao.update(user);
        }
        //上级自动升级市代
        UserEntity top = userDao.get(user.getPid());
        LevelEntity topLevel = levelDao.get(top.getLevelId());
        if (topLevel.getLv() > 7) {
            top.setLevelId(47L);
            userDao.update(top);
        }
        //省代理 10个市代就升级省代
        Integer sumUser = userDao.sumUserByPidAndLevel(top.getId(), 47L);
        if (sumUser >= 9 && topLevel.getLv() > 6) {
            top.setLevelId(46L);
            userDao.update(top);
        }
    }


    //注意组合订单的支付
    public void afterPayOrder(String orderNo) {
        MallOrderEntity orderEntity = findByOrderNo(orderNo);
        if (orderEntity != null) {
            afterPayOrder(orderEntity);
        } else {
            List<String> orderNos = orderUnionService.findByUnionNo(orderNo);
            for (String tem : orderNos) {
                orderEntity = findByOrderNo(tem);
                afterPayOrder(orderEntity);
            }
        }
    }


    //公益基金通知
    void noticeWelFare(MallOrderEntity mallOrderEntity) {
        if (mallOrderEntity != null) {
            List<OrderItemEntity> itemEntities = itemDao.findByOrderId(mallOrderEntity.getId());
            for (OrderItemEntity itemEntity : itemEntities) {
                MallGoodsEntity goods = this.mallGoodsDao.get(itemEntity.getGoodsId());
                if (goods != null && goods.getSaleType() != null && goods.getSaleType().equals(MallGoodsSaleTypeEnum.LOTTERY.getIndex())) {
                    return;
                }
            }
        }
        UserEntity userEntity = userDao.get(mallOrderEntity.getUserId());
        AccountRecordEntity accountRecordEntity = new AccountRecordEntity(Const.ADMIN_ID, mallOrderEntity.getUserId(), AccountRecordTypeEnum.WELFARE.getIndex(), new BigDecimal(mallOrderEntity.getQuantity() * 0.1), null, null, mallOrderEntity.getPayTime(), userEntity.getName() + Const.BUY_ORDER_NO + mallOrderEntity.getOrderNo(), AccountRecordStatusEnum.WAIT.getIndex(), AccountRecordBusEnum.SHARE_REWARD.getIndex());
        accountRecordDao.save(accountRecordEntity);
        //通知
        noticeService.noticeWelFare(userEntity.getOpenId(), userEntity.getName(), new BigDecimal(mallOrderEntity.getQuantity() * 0.1));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MallOrderEntity adminPay(Long orderId) {
        MallOrderEntity mallOrderEntity = get(orderId);
        if (mallOrderEntity.getOrderStatus().equals(MallOrderPayStatusEnum.PAID.getIndex())) {
            throw new RRException("请勿重复支付!");
        }
        afterPayOrder(mallOrderEntity);
        return mallOrderEntity;
    }

    //计算代理产品价格
    void calculatePrice(Long fromUserId, Long userId, OrderItemEntity itemEntity, Boolean flag) {
        MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(itemEntity.getGoodsId());
        //零售产品跳过
        if (!mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.AGENT.getIndex())&&!mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.DAY_SEL.getIndex())) {
            return;
        }
        //获取公司外  价格最低的价格
        PriceEntity priceEntity;
        UserEntity from = userDao.get(fromUserId);
        UserEntity user = userDao.get(userId);
        PriceEntity fromUserPrice = priceService.findByUserIdAndGoodsIdAndCode(fromUserId, itemEntity.getGoodsId(), from.getTCode());
        PriceEntity toUserPrice = priceService.findByUserIdAndGoodsIdAndCode(userId, itemEntity.getGoodsId(), user.getTCode());
        if (fromUserId.equals(Const.ADMIN_ID)) {
            //计算级别
            priceEntity = toUserPrice;
        } else if (userId.equals(Const.ADMIN_ID)) {
            //计算级别
            priceEntity = fromUserPrice;
        } else {
            if (flag) {
                priceEntity = toUserPrice;
            } else {
                //选取高价
                if (fromUserPrice.getPrice().compareTo(toUserPrice.getPrice()) > 0) {
                    priceEntity = fromUserPrice;
                } else {
                    priceEntity = toUserPrice;
                }
            }
        }
        itemEntity.setPrice(priceEntity.getPrice());
    }

    @Autowired
    private LogRuleService logRuleService;
    @Autowired
    private ShopLogTemDao shopLogTemDao;

    //计算订单明细所有产品物流费总数 TODO 根据sku的重量收取邮费
    @Override
    public BigDecimal computeLogFee(List<? extends ItemVo> items, String province) {
        BigDecimal logFee = BigDecimal.ZERO;
        Map<Long, List<ItemVo>> list = new HashMap<>();
        for (ItemVo item : items) {
            MallGoodsEntity goodsEntity = mallGoodsDao.get(item.getGoodsId());
            //店铺计重的产品 进行分单
            if (goodsEntity.getUserId() != null && goodsEntity.getLogType() == MallGoodsLogTypeEnum.WEIGHT.getIndex() && goodsEntity.getLogTemId() != null) {
                if (list.get(goodsEntity.getUserId()) == null) {
                    List<ItemVo> array = new ArrayList<>();
                    array.add(item);
                    list.put(goodsEntity.getUserId(), array);
                } else {
                    list.get(goodsEntity.getUserId()).add(item);
                }
                continue;
            }
            // 不是店铺的or不是计重的 直接计算物流费
            logFee = logFee.add(computeLogFee(goodsEntity, item.getQuantity(), province));
        }
        //计算店铺计重的物流费
        logFee = computeWeightLogFee(list, province, logFee);
        return logFee;
    }

    @Autowired
    private ShopLogRuleDao shopLogRuleDao;

    BigDecimal computeWeightLogFee(Map<Long, List<ItemVo>> list, String province, BigDecimal logFee) {

        //遍历分单后的产品
        if (!list.isEmpty()) {
            Set<Long> keySet = list.keySet();
            for (Long userId : keySet) {
                Map<Long, List<ItemVo>> shopTemMap = new HashMap<>();
                for (ItemVo item : list.get(userId)) {
                    //获取店铺的运费模板
                    MallGoodsEntity goodsEntity = mallGoodsDao.get(item.getGoodsId());
                    ShopLogTemEntity shopLogTemEntity = shopLogTemDao.get(goodsEntity.getLogTemId());
                    //根据运费模板分开
                    if (shopTemMap.get(shopLogTemEntity.getId()) == null) {
                        List<ItemVo> array = new ArrayList<>();
                        array.add(item);
                        shopTemMap.put(shopLogTemEntity.getId(), array);
                    } else {
                        shopTemMap.get(shopLogTemEntity.getId()).add(item);
                    }
                }
                //
                Set<Long> shopTemKeySet = shopTemMap.keySet();
                BigDecimal logfee = BigDecimal.ZERO;  //物流费
                //遍历根据模板分单后的产品
                for (Long tempId : shopTemKeySet) {
                    ShopEntity shopEntity = null;
                    BigDecimal weight = BigDecimal.ZERO; //总重量
                    for (ItemVo item : shopTemMap.get(tempId)) {
                        MallGoodsEntity goodsEntity = mallGoodsDao.get(item.getGoodsId());
                        shopEntity = shopDao.findByUserId(goodsEntity.getUserId());
                        //该模板下的产品重量之和
                        weight = weight.add(goodsEntity.getWeight().multiply(new BigDecimal(item.getQuantity())));
                    }
                    //该模板的运费
                    BigDecimal fee = sumLogFee(weight, tempId, province);
                    //获取运费设置
                    Integer status = shopLogTemDao.findShopLog(shopEntity.getId());
                    //最低计算
                    if (status == ShopLogStatusEnum.LOWEST.getIndex()) {
                        if (fee.compareTo(logfee) < 0 || logfee == BigDecimal.ZERO) {
                            logfee = fee;
                        }
                    }
                    //最高计算
                    if (status == ShopLogStatusEnum.HIGHEST.getIndex()) {
                        if (fee.compareTo(logfee) > 0) {
                            logfee = fee;
                        }
                    }
                    //累计计算
                    if (status == ShopLogStatusEnum.TOTAL.getIndex()) {
                        logfee = logfee.add(fee);
                    }
                }
                logFee = logFee.add(logfee);
            }
        }
        return logFee;
    }

    //总物流费
    BigDecimal sumLogFee(BigDecimal weight, Long logTemId, String province) {
        ShopLogTemEntity shopLogTemEntity = shopLogTemDao.get(logTemId);
        ShopLogRuleEntity shopLogRuleEntity = getLogRule(province, shopLogTemEntity);
        return computeShopLogFee(shopLogRuleEntity, weight);
    }

    public BigDecimal computeShopLogFee(ShopLogRuleEntity shopLogRuleEntity, BigDecimal weight) {
        //在首重内
        if (weight.compareTo(new BigDecimal(shopLogRuleEntity.getFw())) < 1) {
            return shopLogRuleEntity.getFp();
        } else {
            //首重
            BigDecimal fw = new BigDecimal(shopLogRuleEntity.getFw());
            //首重价格
            BigDecimal fp = shopLogRuleEntity.getFp();
            //超出重量  向上取整
            int tem = weight.setScale(0, BigDecimal.ROUND_UP).intValue();
            weight = new BigDecimal(tem);
            BigDecimal upWeight = weight.subtract(fw);
            //续重价格
            BigDecimal up = shopLogRuleEntity.getUp();
            //超出首重范围
            return fp.add(upWeight.multiply(up));
        }
    }

    private ShopLogRuleEntity getLogRule(String province, ShopLogTemEntity shopLogTemEntity) {
        //获取物流规则
        List<ShopLogRuleEntity> ruleEntityList = shopLogRuleDao.findByTemId(shopLogTemEntity.getId());
        ShopLogRuleEntity shopLogRule = null;
        for (ShopLogRuleEntity shopLogRuleEntity : ruleEntityList) {
            //获取该省的物流规则 如果没有设置则获取默认规则
            if (shopLogRuleEntity.getStatus() == ShopLogRuleStatusEnum.YES.getIndex()) {
                shopLogRule = shopLogRuleEntity;
            }
            if (shopLogRuleEntity.getProvince().contains(province)) {
                shopLogRule = shopLogRuleEntity;
                break;
            }
        }
        return shopLogRule;
    }

    //计算单个产品的物流费
    BigDecimal computeLogFee(MallGoodsEntity goodsEntity, Integer quantity, String province) {
        //包邮产品 或者  没有设置邮费
        if (goodsEntity.getLogType() == null || goodsEntity.getLogType().equals(MallGoodsLogTypeEnum.FREE.getIndex())) {
            return BigDecimal.ZERO;
        }
        //满免
        if (goodsEntity.getLogType().equals(MallGoodsLogTypeEnum.FULL.getIndex())) {
            //数量不够免物流费
            if (goodsEntity.getFullNumber() > quantity) {
                return goodsEntity.getLogFee().multiply(new BigDecimal(quantity));
            }
        }
        //计重
        if (goodsEntity.getLogType().equals(MallGoodsLogTypeEnum.WEIGHT.getIndex())) {
            BigDecimal result = BigDecimal.ZERO;
          /*  //如果是店铺的产品 获取物流模板
            if (goodsEntity.getUserId() != null && goodsEntity.getLogTemId() != null){
                //计算物流费
                Integer tem = quantity > goodsEntity.getPerBox() ? quantity : goodsEntity.getPerBox() ;
                result = result.add(logRuleService.computeLogFee(province, goodsEntity.getWeight().multiply(new BigDecimal(tem)),goodsEntity.getLogTemId()));

            }else*/
            {
                //每箱子重新计算一次
                while (quantity > 0) {
                    Integer tem = quantity > goodsEntity.getPerBox() ? goodsEntity.getPerBox() : quantity;
                    result = result.add(logRuleService.computeLogFee(province, goodsEntity.getWeight().multiply(new BigDecimal(tem)), goodsEntity.getName()));
                    quantity = quantity - goodsEntity.getPerBox().intValue();
                }
            }
            return result;
        }
        return BigDecimal.ZERO;
    }


//    @Override
//    public Long commitOrder(Long userId, Long goodsId, String skuName, Integer quantity, AddressEntity address) {
//        //生成订单
//        MallOrderEntity orderEntity = new MallOrderEntity(createNO(userId), userId, new Date(), MallOrderPayStatusEnum.NOT_PAID.getIndex(), address.getName(), address.getMobile(), address.getAddress(), MallOrderOrderStatusEnum.NEW.getIndex());
//        mallOrderDao.save(orderEntity);
//        MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(goodsId);
//        //生成明细
//        OrderItemEntity orderItemEntity = new OrderItemEntity(orderEntity.getId(), goodsId, skuName, mallGoodsEntity.getName(), mallGoodsEntity.getNowPrice(), mallGoodsEntity.getWeight(), mallGoodsEntity.getImg(), quantity);
//        orderItemDao.save(orderItemEntity);
//        //更新总数
//        orderEntity.setQuantity(1);
//        orderEntity.setPrice(mallGoodsEntity.getNowPrice());
//        return orderEntity.getId();
//    }

    @Autowired
    private ShopDao shopDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<MallOrderVo> listOrder(Long userId, int page, int limit, Integer orderType, Integer busType) {
        PageHelper.startPage(page, limit).setOrderBy("mallOrder.id desc");
        List<MallOrderVo> orderVos = mallOrderDao.findByUserId(userId, orderType, busType);
        //组装明细
        for (MallOrderVo orderVo : orderVos) {
            List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(orderVo.getMallOrder().getId());
            orderVo.getMallOrder().setItems(itemEntities);
            //获取店铺
            ShopEntity shopEntity = null;
            if (orderVo.getMallOrder().getShopId() != null) {
                shopEntity = shopDao.findByUserId(orderVo.getMallOrder().getShopId());
            } else {
                shopEntity = shopDao.findByUserId(orderVo.getMallOrder().getFromUserId());
            }
            if (shopEntity != null) {
                orderVo.setShopEntity(shopEntity);
            }
        }

        return orderVos;
    }

    @Override
    public List<MallOrderVo> listShareOrder(Long userId, int page, int limit,Integer type) {
        PageHelper.startPage(page, limit).setOrderBy("mallOrder.id desc");
        List<MallOrderVo> orderVos = mallOrderDao.findByTeamOrShareUserId(userId,type);
        //组装明细
        for (MallOrderVo orderVo : orderVos) {
            List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(orderVo.getMallOrder().getId());
            orderVo.getMallOrder().setItems(itemEntities);
            //获取店铺
            ShopEntity shopEntity = null;
            if (orderVo.getMallOrder().getShopId() != null) {
                shopEntity = shopDao.findByUserId(orderVo.getMallOrder().getShopId());
            } else {
                shopEntity = shopDao.findByUserId(orderVo.getMallOrder().getFromUserId());
            }
            if (shopEntity != null) {
                orderVo.setShopEntity(shopEntity);
            }
        }

        return orderVos;
    }

    /**
     * Long
     * 根据用户id以及订单状态去查询订单明细
     *
     * @param userId
     * @param status
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<MallOrderVo> findByUserIdAndStatus(Long userId, int status) {

        List<MallOrderVo> orderVos = mallOrderDao.queryByUserIdAndStatus(userId, status);
        //组装明细
        for (MallOrderVo orderVo : orderVos) {
            List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(orderVo.getMallOrder().getId());
            orderVo.getMallOrder().setItems(itemEntities);
        }
        return orderVos;
    }

 /*   @Override
    public List<MallOrderEntity> findReturn(String orderNo) {
        return mallOrderDao.findByRemarkAndBusType(orderNo, MallOrderBusTypeEnum.RETURN.getIndex());
    }*/

    /**
     * 根据收款记录去找自动进货的订单
     *
     * @param recordInfo
     * @return
     */
    @Override
    public MallOrderEntity findAutoBuy(String recordInfo) {
        if (recordInfo != null && recordInfo.contains(Const.ORDER_NO)) {
            String orderNo = recordInfo.split(Const.ORDER_NO)[1];
            return mallOrderDao.findByRemarkAndBusType(orderNo, MallOrderBusTypeEnum.AUTO_BUY.getIndex());
        }
        return mallOrderDao.findByRemarkAndBusType(recordInfo, MallOrderBusTypeEnum.AUTO_BUY.getIndex());
    }

    @Override
    public MallOrderEntity buildBackOrder(MallOrderEntity orderEntity) {
        orderEntity.setId(null);
        orderEntity.setFromUserId(orderEntity.getUserId());
        orderEntity.setUserId(orderEntity.getFromUserId());
        orderEntity.setBusType(MallOrderBusTypeEnum.BACK.getIndex());
        orderEntity.setOrderNo(createNO(orderEntity.getUserId()));
        orderEntity.setRemark(orderEntity.getRemark().replace(Const.BUY_ORDER_NO, Const.BACK_ORDER_NO));
        return orderEntity;
    }


    /*****后台部分*****/


    @Override
    public List<MallOrderVo> queryListVo(MallOrderVo mallOrderVo, Long userId) {
        if (userId != null) {
            mallOrderVo.getMallOrder().setShopId(userId);
            mallOrderVo.getFromUser().setId(userId);
            //   mallOrderVo.setBusType(MallOrderBusTypeEnum.BUY.getIndex());
        }
//        //根据店铺查询
//        if (mallOrderVo.getShopEntity().getName() != null && !"".equals(mallOrderVo.getShopEntity().getName())) {
//            mallOrderVo.getMallOrder().setOrderType(MallOrderOrderTypeEnum.DELIVERY.getIndex());
//            mallOrderVo.getMallOrder().setBusType(MallOrderBusTypeEnum.BUY.getIndex());
//        }
        return mallOrderDao.queryListVo(mallOrderVo);
    }

    @Override
    public MallOrderVo getVo(Long id) {
        return mallOrderDao.getVo(id);
    }

    @Override
    public MallOrderVo getVo(String orderNo) {
        return mallOrderDao.getVoByOrderNo(orderNo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(MallOrderVo mallOrderVo) {
        List<OrderItemEntity> itemEntities = mallOrderVo.getMallOrder().getItems();
        UserEntity fromUser = mallOrderVo.getFromUser();
        UserEntity toUser = mallOrderVo.getUser();
        //验证账户
        userService.validateUser(fromUser, toUser);
        fromUser = userDao.findByCode(fromUser.getCode());
        toUser = userDao.findByCode(toUser.getCode());
        String remark = mallOrderVo.getMallOrder().getRemark();
        Integer orderType = mallOrderVo.getMallOrder().getOrderType();
        if (orderType == null) {
            orderType = MallOrderOrderTypeEnum.TRANSFER.getIndex();
        }
        //验证明细
        validateSendOrder(itemEntities, fromUser.getId(), toUser.getId(), orderType);
        //生成订单
        List<MallOrderEntity> mallOrderEntities = buildSendOrder(fromUser.getId(), toUser.getId(), orderType, mallOrderVo.getMallOrder().getProvince(), mallOrderVo.getMallOrder().getCity(), mallOrderVo.getMallOrder().getCounty(), mallOrderVo.getMallOrder().getDetail(), mallOrderVo.getMallOrder().getUserName(), mallOrderVo.getMallOrder().getMobile(), remark, itemEntities);
        //实体化
        // mallOrderDao.update(mallOrderEntity);

        for (MallOrderEntity mallOrderEntity : mallOrderEntities) {
            //转货操作
            mallStoreService.transfer(mallOrderEntity.getId());
            //支付物流费 谁发货扣谁的
            accountService.pay(mallOrderEntity.getFromUserId(), AccountTypeEnum.CASH.getIndex(), mallOrderEntity.getLogFee(), mallOrderEntity.getOrderNo());
            //结算店铺利润
            if (mallOrderEntity.getOrderType().equals(MallOrderOrderTypeEnum.DELIVERY.getIndex()) && mallOrderEntity.getBusType().equals(MallOrderBusTypeEnum.SEND.getIndex())) {
                List<OrderItemEntity> itemEntityList = orderItemDao.findByOrderId(mallOrderEntity.getId());
                for (OrderItemEntity itemEntity : itemEntityList) {
                    MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(itemEntity.getGoodsId());
                    SaleTypeInfoEntity saleTypeInfoEntity = saleTypeInfoDao.findByGoodsId(mallGoodsEntity.getId());
                    // 给予区域
                    if (saleTypeInfoEntity.getAreaReward() != null && !saleTypeInfoEntity.getAreaReward().equals("")) {
                        mallActService.fireAreaAct(mallOrderEntity.getOrderNo(), mallOrderEntity.getProvince(), mallOrderEntity.getCity(), mallOrderEntity.getCounty(), itemEntity.getQuantity(), saleTypeInfoEntity.getAreaType(), mallOrderEntity.getUserId(), saleTypeInfoEntity.getAreaReward(), mallGoodsEntity);
                    }
                    //结算店铺利润
                    if (mallGoodsEntity.getUserId() != null) {
                        accountService.shopProfit(mallGoodsEntity.getUserId(), getShopProfit(mallOrderEntity), userDao.get(mallOrderEntity.getUserId()).getName(), mallOrderEntity.getOrderNo());
                    }
                }
            }
            //通知
            noticeOrder(mallOrderEntity);
        }
        //转货返经验值
//        transferChangeExp(mallOrderEntity, true);


    }


    /**
     * 转货业务改变经验值
     *
     * @param orderEntity
     */
    void transferChangeExp(MallOrderEntity orderEntity, boolean reward) {
        LevelEntity fl = levelDao.findByUserId(orderEntity.getFromUserId());
        LevelEntity tl = levelDao.findByUserId(orderEntity.getUserId());
        //公司或者高级别转给你的
        if (orderEntity.getFromUserId().equals(Const.ADMIN_ID) || fl.compareTo(tl) > 0) {
            UserEntity userEntity = userDao.get(orderEntity.getUserId());
            accountService.rewardExp(orderEntity.getUserId(), orderEntity.getPrice(), orderEntity.getOrderNo(), userEntity.getName(), reward);
        }
        //转给比自己级别低的 或者转给公司
        if (orderEntity.getUserId().equals(Const.ADMIN_ID) || fl.compareTo(tl) < 0) {
            UserEntity userEntity = userDao.get(orderEntity.getFromUserId());
            accountService.backExp(orderEntity.getFromUserId(), orderEntity.getPrice(), orderEntity.getOrderNo(), userEntity.getName());
        }

    }

    @Autowired
    private SysUsersService sysUsersService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void downLoad(HttpServletResponse response, HttpServletRequest request) {
        Long start = System.currentTimeMillis();
        Long sysUserId = ShiroUtils.getUserId();
        Long fromUserId = sysUsersService.findBySysUserId(sysUserId);
        List<Long> ids = new ArrayList<>();
        List<OrderDownVo> datas = new ArrayList<>();
        List<MallOrderEntity> mallOrderEntities = mallOrderDao.findNotDelivered(fromUserId);
        System.out.println("====查询订单时间===>" + (System.currentTimeMillis() - start));
        Map<String, Integer> dataSum = new HashMap<>();
        mallOrderEntities.forEach(mallOrderEntity -> {
            OrderDownVo orderDownVo = new OrderDownVo();
            orderDownVo.setId(mallOrderEntity.getId());
            orderDownVo.setUserName(mallOrderEntity.getUserName());
            orderDownVo.setRemark(mallOrderEntity.getRemark());
            //编码
            UserEntity user = userDao.get(mallOrderEntity.getUserId());
            orderDownVo.setMobile(mallOrderEntity.getMobile() + " " + user.getCode());
            orderDownVo.setAddress(mallOrderEntity.getAddress());
            orderDownVo.setOrderNo(mallOrderEntity.getOrderNo());
            orderDownVo.setLogFee(mallOrderEntity.getLogFee());
            StringBuffer sb = new StringBuffer();
            List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(mallOrderEntity.getId());
            itemEntities.forEach(orderItemEntity -> {
                String skuName = orderItemEntity.getSkuName();
                MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(orderItemEntity.getGoodsId());
                if (skuName == null) skuName = "";
                String goodsName = mallGoodsEntity.getRemark();
                if (goodsName == null) {
                    goodsName = mallGoodsEntity.getName();
                }
                String str = goodsName + skuName + "X" + orderItemEntity.getQuantity() + "(" + mallGoodsEntity.getUnit() + ")  ";
                sb.append(str);
                //统计总数
                String key = goodsName + skuName + " " + mallGoodsEntity.getUnit();
                Integer quantity = 0;
                if (dataSum.containsKey(key)) {
                    quantity = dataSum.get(key);
                }
                quantity += orderItemEntity.getQuantity();
                dataSum.put(key, quantity);
            });
            orderDownVo.setDetail(sb.toString());
            datas.add(orderDownVo);
            ids.add(mallOrderEntity.getId());
        });
        //更新
        if (ids.size() > 0) {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
            try {
                ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
                WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "订单").head(OrderDownVo.class).build();
                excelWriter.write(datas, writeSheet1);
//                EasyExcel.write(response.getOutputStream(), OrderDownVo.class).sheet(0,"订单").doWrite(datas);
                //汇总
                List<OrderSumVo> orderSumVos = new ArrayList<>();
                dataSum.keySet().forEach(key -> {
                    OrderSumVo orderSumVo = new OrderSumVo(key, dataSum.get(key));
                    orderSumVos.add(orderSumVo);
                });
                WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "汇总").head(OrderSumVo.class).build();
                System.out.println("=========>" + (System.currentTimeMillis() - start));
                excelWriter.write(orderSumVos, writeSheet2);
                excelWriter.finish();
                System.out.println("=========>" + (System.currentTimeMillis() - start));
//                EasyExcel.write(response.getOutputStream(), OrderSumVo.class).sheet(1,"汇总").doWrite(orderSumVos);
                mallOrderDao.updateDelivering(ids);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void downLoadOrder(HttpServletResponse response,SearchParam<MallOrderVo> params) {
        List<OrderDownListVo> datas = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        Date time = cal.getTime();
        String format = sdf.format(time);
        //查询所有订单
        List<MallOrderEntity> mallOrderEntities = mallOrderDao.findByDate(params.getEntity().getMallOrder().getOrderTimes()[0],params.getEntity().getMallOrder().getOrderTimes()[1]);
        mallOrderEntities.forEach(mallOrderEntity -> {
            OrderDownListVo orderDownListVo = new OrderDownListVo();
//            orderDownListVo.setBusType();
            if (mallOrderEntity.getBusType().equals(MallOrderBusTypeEnum.BUY.getIndex()) && mallOrderEntity.getFromUserId() != null) {
                ShopEntity shop = shopDao.findByUserId(mallOrderEntity.getFromUserId());
                if (shop != null) {
                    orderDownListVo.setShop(shop.getName());
                } else {
                    orderDownListVo.setShop("社集优选");
                }
            } else {
                orderDownListVo.setShop("社集优选");

            }


            UserEntity userEntity = userDao.get(mallOrderEntity.getFromUserId());
            if (userEntity != null) {
                orderDownListVo.setUser(userEntity.getCode() + "-" + userEntity.getName());
            }
            UserEntity user = userDao.get(mallOrderEntity.getUserId());
            if (user != null) {
                orderDownListVo.setToUser(user.getCode() + "-" + user.getName());
            }
            if (mallOrderEntity.getOrderStatus() != null) {
                orderDownListVo.setOrderStatus(MallOrderOrderStatusEnum.indexOf(mallOrderEntity.getOrderStatus()));
            }
            if (mallOrderEntity.getPayStatus() != null) {
                orderDownListVo.setPayStatus(MallOrderPayStatusEnum.indexOf(mallOrderEntity.getPayStatus()));
            }
            orderDownListVo.setAddress(mallOrderEntity.getAddress());
            orderDownListVo.setTime(mallOrderEntity.getOrderTime());
            //订单类型
            if (mallOrderEntity.getOrderType() != null) {
                orderDownListVo.setOrderType(MallOrderOrderTypeEnum.indexOf(mallOrderEntity.getOrderType()));
            }
            orderDownListVo.setOrderNo(mallOrderEntity.getOrderNo());
            if (mallOrderEntity.getBusType() != null) {
                orderDownListVo.setBusType(MallOrderBusTypeEnum.indexOf(mallOrderEntity.getBusType()));
            }
            if (mallOrderEntity.getMention() != null) {
                orderDownListVo.setIsSelf(YesNoEnum.indexOf(mallOrderEntity.getMention()));
            }
            StringBuffer sb = new StringBuffer();
            List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(mallOrderEntity.getId());
            itemEntities.forEach(orderItemEntity -> {
                String skuName = orderItemEntity.getSkuName();
                MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(orderItemEntity.getGoodsId());
                if (skuName == null) skuName = "";
                if (mallGoodsEntity.getUnit() == null) mallGoodsEntity.setUnit("");
                String str = orderItemEntity.getName() + skuName + "X" + orderItemEntity.getQuantity() + "(" + mallGoodsEntity.getUnit() + ")  ";
                sb.append(str);
            });
            orderDownListVo.setQuantity(mallOrderEntity.getQuantity());
            orderDownListVo.setDetail(sb.toString());
            datas.add(orderDownListVo);
        });
        //更新
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
        try {
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "订单").head(OrderDownListVo.class).build();
            excelWriter.write(datas, writeSheet1);
            excelWriter.finish();
//                EasyExcel.write(response.getOutputStream(), OrderSumVo.class).sheet(1,"汇总").doWrite(orderSumVos);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    @Autowired
    private SysUsersDao sysUsersDao;

    //ID 单号 物流公司 物流费
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upload(InputStream inputStream) {
        EasyExcel.read(inputStream, OrderUpVo.class, new UploadDataListener()).sheet().doRead();
    }

    class UploadDataListener extends AnalysisEventListener<OrderUpVo> {


        @Override
        @Transactional(rollbackFor = Exception.class)
        public void invoke(OrderUpVo orderUpVo, AnalysisContext analysisContext) {
            MallOrderEntity mallOrderEntity = mallOrderDao.get(orderUpVo.getId());
            Long sysUserId = ShiroUtils.getUserId();
            Long userId = sysUsersDao.findBySysUserId(sysUserId);
            // 判断是否为自己的订单 为空则是公司
            if (userId != null) {
                if (!mallOrderEntity.getFromUserId().equals(userId)) {
                    throw new RRException("只能上传自己的订单记录");
                }
                if (mallOrderEntity.getShopId() != null && !mallOrderEntity.getShopId().equals(userId)) {
                    throw new RRException("只能上传自己的订单记录");
                }
            }
            mallOrderEntity.setLogCompany(orderUpVo.getLogCompany());
            mallOrderEntity.setLogNo(orderUpVo.getLogNo());
            mallOrderEntity.setOrderStatus(MallOrderOrderStatusEnum.DELIVERED.getIndex());
            mallOrderEntity.setDeliverTime(new Date());
            //退物流费
            backLogFee(orderUpVo.getId(), orderUpVo.getLogFee());
            mallOrderEntity.setLogFee(orderUpVo.getLogFee());
            mallOrderDao.update(mallOrderEntity);
            //通知发货
            UserEntity userEntity = userDao.get(mallOrderEntity.getUserId());
            noticeService.sendOrderLog(userEntity.getOpenId(), mallOrderEntity.getOrderNo(), userEntity.getName(), mallOrderEntity.getLogCompany(), mallOrderEntity.getLogNo(), mallOrderEntity.getAddress());
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        }

    }

    @Autowired
    private OrderItemDao itemDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    // 商城未支付状态 退券   商城已支付的未发货   后台未发货
    public MallOrderEntity deleteOrder(Long userId, Long orderId) {
        MallOrderEntity mallOrderEntity = get(orderId);
        if (userId.equals(mallOrderEntity.getFromUserId())) {
            userId = Const.ADMIN_ID;
        }
        //然后再执行 否则有并发问题
        if (!mallOrderEntity.getCancel()) {
            throw new RRException("订单属于不可取消状态!");
        }

        if (!mallOrderEntity.getOrderStatus().equals(MallOrderOrderStatusEnum.NEW.getIndex()) && mallOrderEntity.getOrderType().equals(MallOrderOrderTypeEnum.DELIVERY.getIndex()) && mallOrderEntity.getBusType().equals(MallOrderBusTypeEnum.SEND.getIndex())) {
            throw new RRException("不能取消该订单，请联系管理员");
        }
        //更新为已取消状态
        mallOrderEntity.setOrderStatus(MallOrderOrderStatusEnum.CANCELED.getIndex());
        mallOrderDao.update(mallOrderEntity);

        // 不是自己的订单
        if (mallOrderEntity == null || (!userId.equals(Const.ADMIN_ID) && !mallOrderEntity.getUserId().equals(userId))) {
            throw new RRException("只能取消自己的订单!");


        }


        //支付的 超过退货期  如果是后台操作 则不限制时间
        if (!userId.equals(Const.ADMIN_ID)) {
            if (!mallOrderEntity.getBusType().equals(MallOrderBusTypeEnum.SEND.getIndex()) && mallOrderEntity.getPayStatus().equals(MallOrderPayStatusEnum.PAID.getIndex()) && DateUtil.getHours(mallOrderEntity.getOrderTime(), new Date()) >= Const.HOUR) {
                throw new RRException("已超过取消时间,请联系客服处理!");
            }
        }

        List<OrderItemEntity> orderItemEntities = orderItemDao.findByOrderId(mallOrderEntity.getId());
        orderItemEntities.forEach(item->{
            if(item.getName().contains("好物团品")){
                throw new RRException("团购退货请联系授权号!");
            }
        });

        cancelAct(mallOrderEntity);
        cancelReward(mallOrderEntity);
        renewStock(mallOrderEntity);
        removeShare(mallOrderEntity.getOrderNo());
        removeSale(mallOrderEntity.getOrderNo());
        return mallOrderEntity;

    }

    private void renewStock(MallOrderEntity mallOrderEntity) {
        //只有已支付的订单取消才还原库存
        if (mallOrderEntity.getPayStatus() == MallOrderPayStatusEnum.PAID.getIndex()) {
            List<OrderItemEntity> items = orderItemDao.findByOrderId(mallOrderEntity.getId());
            //获取该订单的详情item
            for (OrderItemEntity item : items) {
                MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(item.getGoodsId());
                mallGoodsEntity.setStock(mallGoodsEntity.getStock() + item.getQuantity());
                mallGoodsDao.update(mallGoodsEntity);
            }
        }
        //该订单如果存在活动产品 则需要还原活动库存
        List<OrderItemEntity> itemEntities = itemDao.findByOrderId(mallOrderEntity.getId());
        for (OrderItemEntity item : itemEntities) {
            MallActEntity actEntity = mallActDao.findByGoodsIdAndstatus(item.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
            if (actEntity != null) {
                if (actEntity.getStock() != null && !actEntity.getStock().equals("")) {
                    actEntity.setStock(item.getQuantity() + actEntity.getStock());
                    mallActDao.update(actEntity);
                }
            }
        }
    }

    /**
     * 判断是否有奖品限制
     *
     * @param mallOrderEntity
     */
    private void cancelAct(MallOrderEntity mallOrderEntity) {

        List<OrderItemEntity> itemEntities = itemDao.findByOrderId(mallOrderEntity.getId());
        for (OrderItemEntity itemEntity : itemEntities) {
            MallActEntity mallActEntity = mallActDao.findByGoodsIdAndstatus(itemEntity.getGoodsId(), MallActStatusEnum.OPEN.getIndex());
            //是否有绑定抽奖
            if (mallActEntity != null && mallActEntity.getBindLotteryId() != null) {
                List<LotteryRecordEntity> lotteryRecordEntities = lotteryRecordDao.findByOrderNo(mallOrderEntity.getOrderNo());
                if (lotteryRecordEntities != null && lotteryRecordEntities.size() > 0) {
                    throw new RRException("您已参与抽奖");
                }
                lotteryRecordDao.deleteByOrderNo(mallOrderEntity.getOrderNo());
            }
            // 奖品不能取消订单
            if (itemEntity != null && itemEntity.getGoodsId() != null) {
                MallGoodsEntity mallGoodsEntity = mallGoodsDao.get(itemEntity.getGoodsId());
                if (mallGoodsEntity != null && mallGoodsEntity.getSaleType() != null && mallGoodsEntity.getSaleType().equals(MallGoodsSaleTypeEnum.LOTTERY.getIndex())) {
                    throw new RRException("奖品不能取消");
                }
            }
        }

    }


    @Autowired
    private CouponService couponService;

    private void cancelReward(MallOrderEntity mallOrderEntity) {
        //不管取消什么类型的订单 未支付的退券 已经支付的退券与钱
        accountService.cancel(mallOrderEntity.getOrderNo());
        //取消与恢复卡券
        couponService.cancel(mallOrderEntity.getOrderNo());
        //分场景处理
        Integer orderType = mallOrderEntity.getOrderType();
        Integer busType = mallOrderEntity.getBusType();
        //暂时 商城(未支付发货,未支付转货,已支付发货) 后台(发货订单)
        //商城进货 退钱
        if (MallOrderBusTypeEnum.BUY.getIndex() == busType) {
            //钱与券上面已经退了 触发取消活动
            actService.cancel(mallOrderEntity);
            //未支付的上面已经退券 如下判断已支付发货  已支付的转货是完成状态无法退货无需操作 已经支付的退货(退货款部分)
//            if (payStatus.equals(MallOrderPayStatusEnum.PAID.getIndex())) {
            //商城的 退货 已经退券了 不用退货到库存 只要退给代理 补货的订单
            // mallStoreService.backCod(mallOrderEntity.getOrderNo());
            //追回自动购买的情况
            // mallStoreService.backAutoBuy(mallOrderEntity.getOrderNo());
            //发货订单退回到仓库
//                if (orderType.equals(MallOrderOrderTypeEnum.DELIVERY.getIndex())) {
//                    退回到代理仓库
//                    mallStoreService.backDelivery(mallOrderEntity.getOrderNo());
//                }
//            }
        }
        //后台发货
        if (MallOrderBusTypeEnum.SEND.getIndex() == busType && orderType.equals(MallOrderOrderTypeEnum.DELIVERY.getIndex())) {
            //退回到代理仓库
            mallStoreService.backDelivery(mallOrderEntity.getOrderNo());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MallOrderEntity mentionOrder(Long orderId) {
        MallOrderEntity mallOrderEntity = mallOrderDao.get(orderId);
        mallOrderEntity.setOrderStatus(MallOrderOrderStatusEnum.DONE.getIndex());
        mallOrderDao.update(mallOrderEntity);
        return mallOrderEntity;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(MallOrderEntity entity) {
        backLogFee(entity);
        super.update(entity);
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void renew() {
        Long sysUserId = ShiroUtils.getUserId();
        Long userId = sysUsersDao.findBySysUserId(sysUserId);
        mallOrderDao.renew(userId);
    }


    @Override
    public void downLoad(HttpServletResponse response, String code, String startDate, String endDate) {
        UserEntity userEntity = userDao.findByCode(code);
        List<MallOrderEntity> mallOrderEntities = mallOrderDao.findUserPaid(userEntity.getId(), DateUtil.getStartTime(startDate), DateUtil.getEndTime(endDate));
        List<OrderSumVo> orderSumVos = sumOrder(mallOrderEntities);
        try {
            // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("结算汇总", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), OrderSumVo.class).sheet("模板").doWrite(orderSumVos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public List<OrderSumVo> sumOrder(List<MallOrderEntity> orderEntities) {
        List<OrderSumVo> orderSumVos = new ArrayList<>();
        Map<String, Integer> orderSum = new HashMap<>();
        orderEntities.forEach(mallOrderEntity -> {
            List<OrderItemEntity> orderItemEntities = orderItemDao.findByOrderId(mallOrderEntity.getId());
            orderItemEntities.forEach(orderItemEntity -> {
                Integer quantity = 0;
                String key = orderItemEntity.getName();
                if (orderSum.containsKey(key)) {
                    quantity = orderSum.get(key);
                }
                quantity += orderItemEntity.getQuantity();
                orderSum.put(key, quantity);
            });
        });
        orderSum.keySet().forEach(key -> {
            OrderSumVo orderSumVo = new OrderSumVo(key, orderSum.get(key));
            orderSumVos.add(orderSumVo);
        });
        return orderSumVos;
    }

    @Override
    public MallOrderEntity findByOrderNo(String orderNo) {
        return mallOrderDao.findByOrderNo(orderNo);
    }

    /**
     * Long
     * 确定收货
     *
     * @param userID
     * @param orderNo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MallOrderEntity sureReceipt(Long userID, String orderNo) {
        MallOrderEntity orderEntity = this.mallOrderDao.findByOrderNo(orderNo);
//        判断订单是否发货了以及是不是它的订单
        if (!userID.equals(orderEntity.getUserId())) {
            throw new RRException("不是他的订单不能确定收货");
        }
        if (MallOrderOrderStatusEnum.DELIVERED.getIndex() != (orderEntity.getOrderStatus()) && orderEntity.getOrderStatus().equals(MallOrderOrderStatusEnum.RECEIVED.getIndex())) {
            throw new RRException("该订单不能确认收货");
        }

        // 确定收货
        orderEntity.setOrderStatus(MallOrderOrderStatusEnum.RECEIVED.getIndex());

        this.mallOrderDao.update(orderEntity);
        this.accountService.doneTransfer(orderNo);
        //确定收货后进行各级代理的分金额
        return orderEntity;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<MallOrderVo> findByFromUserId(Long userId, Integer orderStatus, Integer payStatus, int page,
                                              int limit) {
        PageHelper.startPage(page, limit).setOrderBy("mallOrder.order_time desc");
        List<MallOrderVo> orderVos = this.mallOrderDao.findByFromUserId(userId, orderStatus, payStatus);
        //组装明细
        for (MallOrderVo orderVo : orderVos) {
            List<OrderItemEntity> itemEntities = orderItemDao.findByOrderId(orderVo.getMallOrder().getId());
            orderVo.getMallOrder().setItems(itemEntities);

            //获取店铺
            ShopEntity shopEntity = shopDao.findByUserId(orderVo.getFromUser().getId());
            if (shopEntity != null) {
                orderVo.setShopEntity(shopEntity);
            }
        }
        return orderVos;
    }

    //H5端上传物流单号
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apiUpload(Long userId, Long orderId, String logNo, String logCompany, BigDecimal logFee) {
        MallOrderEntity mallOrderEntity = mallOrderDao.get(orderId);
        // 判断是否为自己的订单 为空则是公司
        if (userId != null && !mallOrderEntity.getFromUserId().equals(userId)) {
            throw new RRException("只能上传自己的订单记录");
        }
        mallOrderEntity.setLogCompany(logCompany);
        mallOrderEntity.setLogNo(logNo);
        mallOrderEntity.setOrderStatus(MallOrderOrderStatusEnum.DELIVERED.getIndex());
        mallOrderEntity.setDeliverTime(new Date());
        //退物流费
        backLogFee(orderId, logFee);
        mallOrderEntity.setLogFee(logFee);
        mallOrderDao.update(mallOrderEntity);
        //通知发货
        UserEntity userEntity = userDao.get(mallOrderEntity.getUserId());
        noticeService.sendOrderLog(userEntity.getOpenId(), mallOrderEntity.getOrderNo(), userEntity.getName(), mallOrderEntity.getLogCompany(), mallOrderEntity.getLogNo(), mallOrderEntity.getAddress());
    }


    @Override
    public Map<String, Object> shopOrderInfo(Long userId) {
        Map<String, Object> map = new HashMap<>();
        BigDecimal totalPrice = BigDecimal.ZERO;
        BigDecimal todayPrice = BigDecimal.ZERO;
        //店铺总订单数
        Integer totalOrderNum = mallOrderDao.totalOrderNum(userId);
        map.put("totalOrderNum", totalOrderNum);
        //店铺总金额
        BigDecimal price = mallOrderDao.totalPrice(userId);
        if (price != null) {
            totalPrice = totalPrice.add(price);
        }
        map.put("totalPrice", totalPrice);
        //店铺今日订单数
        Integer todayOrderNum = mallOrderDao.todayOrderNum(userId);
        map.put("todayOrderNum", todayOrderNum);
        //店铺今日订单金额
        price = mallOrderDao.todayPrice(userId);
        if (price != null) {
            todayPrice = todayPrice.add(price);
        }
        map.put("todayPrice", todayPrice);

        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrder(MallOrderEntity mallOrderEntity) {
        MallOrderEntity orderEntity = mallOrderDao.get(mallOrderEntity.getId());

        if (!orderEntity.getOrderStatus().equals(MallOrderOrderStatusEnum.CANCELED.getIndex()) && mallOrderEntity.getOrderStatus().equals(MallOrderOrderStatusEnum.CANCELED.getIndex())) {
            cancelReward(mallOrderEntity);
        }
        mallOrderDao.update(mallOrderEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoCancelOrder() {
        List<MallOrderEntity> mallOrderEntities = mallOrderDao.autoCancel();
        Date date = new Date();
        if (mallOrderEntities.size() > 0) {
            for (MallOrderEntity mallOrderEntity : mallOrderEntities) {
                long time = date.getTime() - mallOrderEntity.getOrderTime().getTime();
                double result = time * 1.0 / (1000 * 60 * 60);
                if (result >= 24 || result < 0) {
                    //然后再执行 否则有并发问题
                    if (!mallOrderEntity.getCancel()) {
                        throw new RRException("订单属于不可取消状态!");
                    }

                    if (!mallOrderEntity.getOrderStatus().equals(MallOrderOrderStatusEnum.NEW.getIndex()) && mallOrderEntity.getOrderType().equals(MallOrderOrderTypeEnum.DELIVERY.getIndex()) && mallOrderEntity.getBusType().equals(MallOrderBusTypeEnum.SEND.getIndex())) {
                        throw new RRException("不能取消该订单，请联系管理员");
                    }
                    //更新为已取消状态
                    mallOrderEntity.setOrderStatus(MallOrderOrderStatusEnum.CANCELED.getIndex());
                    mallOrderDao.update(mallOrderEntity);

                    cancelAct(mallOrderEntity);
                    cancelReward(mallOrderEntity);
                    renewStock(mallOrderEntity);
                }

            }
        }
    }

    @Autowired
    private AreaDao areaDao;


    @Autowired
    private SmsService smsService;


}